[Haskell-cafe] Using ClassyPrelude to handle either Text or ByteString

Eric Mertens emertens at gmail.com
Fri May 8 22:48:58 UTC 2015


First, we can clean that code:

do xs <- mapM (readFile . fpFromString) (files opts)
   hPut stdout (process opts (concat xs))

You won't be able to make the decision of which type process should work
at inside of process because this decision will also affect which
implementation of readFile is used.

What you will need to do is inspect the 'opts' in the function above
and execute it at a type as determined by the options.

example opts
  | isTextMode opts       = aboveFunctionAsText opts
  | isByteStringMode opts = aboveFunctionAsByteString opts


If you'd like to unify these into a single implementation as above
you'll need to provide some kind of extra information to resolve
the type ambiguity. This would have a type like:

aboveFunctionWithProxy :: IsSequence a => proxy a -> Options -> IO ()

exampleUsingProxies opts
  | isTextMode opts       = aboveFunctionWithProxy (Proxy :: Proxy Text)
opts
  | isByteStringMode opts = aboveFunctionWithProxy (Proxy :: Proxy
ByteString) opts

The proxy parameter could then need to be linked to the type of the
internal xs parameter above using either scoped type variables or
a helper function similar to 'asTypeOf' with with a different type!

On Fri, May 8, 2015 at 1:10 PM, Mike Meyer <mwm at mired.org> wrote:

> Ok, I can't seem to figure out how to make this work, and since I'm using
> ClassyPrelude (from classy-prelude, latest version on hackage as of
> yesterday), I think cafe is a better place to ask than beginners. Sorry if
> this should have gone there.
>
> I want to read in a list of files, concatenate them, and then run the
> resulting data through a "process" function. So far, no problem. Given an
> opts record that contains the list of files and some control for the
> process function, this expression works:
>
> hPut stdout =<< process opts . concat
> <$> mapM (readFile . fpFromString) (files opts)
>
> (BTW, recommendations on cleaning that up gratefully accepted)
>
> However, I'd like to be able to read them all as either Text or
> ByteString, depending on options being passed to me. This doesn't work so
> well. If I give process a type of Text -> Text or ByteString->ByteString,
> everything works fine with no other changes. However, any attempt to make
> it polymorphic fails with ambiguous type warnings.
>
> I've tried a slew of things, and found a few that work. But none of them
> are what I'd call good, much less elegant. Is there a good way to do this?
>
> _______________________________________________
> Haskell-Cafe mailing list
> Haskell-Cafe at haskell.org
> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
>
>


-- 
Eric Mertens
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/haskell-cafe/attachments/20150508/f902b38c/attachment.html>


More information about the Haskell-Cafe mailing list