type inference fails with where clause (RankNTypes, TypeFamilies)
when using RankNTypes
and TypeFamilies
with polymorphic functions, type inference works in let but not in where clauses.
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE TypeFamilies #-}
import Control.Monad
class Monad m => GenM m where
type GenReq m :: *
type GenFun a b = forall m. GenM m => a -> m b
data GenDef a b = GenDef { name :: String, fun :: GenFun a b }
data Gen a b = Gen
data Struct = Struct
mkGen :: forall a b. String -> GenFun a b -> GenDef a b
mkGen = GenDef
runGen :: GenM m => Gen a b -> a -> m (Maybe b)
runGen = undefined
getPatients :: GenM m => m [Int]
getPatients = undefined
-- BROKEN
myGen :: Gen String Struct -> GenDef Int [Struct]
myGen structGen =
mkGen "myGen" $ \pid ->
do pats <- getPatients
structs <- mapM patToStruct pats
return structs
where
patToStruct pid =
do Just struct <- runGen structGen (show pid)
return struct
-- WORKS
myGen' :: Gen String Struct -> GenDef Int [Struct]
myGen' structGen =
mkGen "myGen" $ \pid ->
do pats <- getPatients
let patToStruct pid =
do Just struct <- runGen structGen (show pid)
return struct
structs <- mapM patToStruct pats
return structs
-- WORKS
myGen'' :: Gen String Struct -> GenDef Int [Struct]
myGen'' structGen =
mkGen "myGen" $ \pid ->
do pats <- getPatients
structs <- mapM patToStruct pats
return structs
where
patToStruct :: GenM m => Int -> m Struct
patToStruct pid =
do Just struct <- runGen structGen (show pid)
return struct