functional programming - Transforming functions of type `a -> b` into those of type `String -> String` in Haskell -
my intention simple. want wrap functions of type a -> b string -> string (so bunch of heterogeneous functions can put in list). write:
wrap :: (read a, show b) => (a -> b) -> (string -> string) wrap f = \s -> show $ f (read s :: a) however, ghc complaints:
could not deduce (read a1) arising use of `read' context (read a, show b) bound type signature wrap :: (read a, show b) => (a -> b) -> string -> string i want know why piece of code won't work , kind of hacks needed achieve goal?
thanks.
your code won't work because haskell doesn't re-use or scope type variables; a in wrap :: (read a, show b) => (a -> b) -> (string -> string) different a 1 in read s :: a (and they're both universally quantified). source of a1 in error message; ghc alpha-converting program to
wrap :: (read a, show b) => (a -> b) -> (string -> string) wrap f = \s -> show $ f (read s :: a1) however, f's argument type fixed inside wrap, removing type annotation works fine. function becomes
wrap :: (read a, show b) => (a -> b) -> (string -> string) wrap f = \s -> show $ f (read s) -- or wrap f = show . f . read and can use it:
ghci> map ($ "42") [wrap (+ (7 :: integer)), wrap (* (2.0 :: double))] ["49","84.0"] note means read s has type can't write down. in haskell 2010 (or 98), way around use function astypeof :: -> -> a; astypeof const, type signature, constrains first, returned, argument of same type second. then, of course, you'd have conjure variable of type a. following work that:
wrap :: (read a, show b) => (a -> b) -> (string -> string) wrap f = \s -> show $ f (read s `astypeof` finput) finput = undefined foutput = f finput -- still can't give type signature in ghc, avoid this, can turn on the scopedtypevariables extension; on, if explicitly qualify type variables forall, they'll scoped value-level names. code become
{-# language scopedtypevariables #-} wrap :: forall b. (read a, show b) => (a -> b) -> (string -> string) wrap f = \s -> show $ f (read s :: a) but remember, don't need type annotations @ simple example.
Comments
Post a Comment