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

Popular posts from this blog

plot - Remove Objects from Legend When You Have Also Used Fit, Matlab -

java - Why does my date parsing return a weird date? -

Need help in packaging app using TideSDK on Windows -