问题
I'm playing with haskell-distributed (Cloud Haskell) and I cannot make use of type constraint using returning type (must be as ... -> Process ()
).
To simplify context (and give a reproducible example), let
-- Request / Response
data ReqRes a b = Req a | Res b deriving (Read, Show)
and one generic function mapping generic processes
compute :: (Read a, Read b, Show a, Show b) => (a -> b) -> IO ()
compute f = do
req <- readLn
case req of
Res _ -> error "Req expected"
Req a -> print $ Res $ f a
this cannot compile since req <- readLn
and Res $ f a
cannot deduce b
type and a
types respectively.
My solution is use a variant of const
to "link / constraint" both expressions:
linkType :: a -> a -> a
linkType = flip const
compute' :: (Read a, Read b, Show a, Show b) => (a -> b) -> IO ()
compute' f = do
req <-readLn
case req of
Res _ -> error "Req expected"
Req a -> print $ linkType req $ Res $ f a
now compile and works fine
> compute' (2 *)
Req 12
Res 24
> compute' (show :: Int -> String)
Req 12
Res "12"
but I wish to know the correct way to do this kind of things.
Thank you!
来源:https://stackoverflow.com/questions/35927439/how-to-conciliate-constraint-types-between-two-separated-expressions