我有以下来自haskell book的代码片段:
embedded' :: MaybeT (ExceptT String (ReaderT () IO)) Int
embedded' = MaybeT (ExceptT (ReaderT (const (return (Right (Just 1))))))
ExceptT
的类型签名如下:
newtype ExceptT e m a =
ExceptT { runExceptT :: m (Either e a)) }
将embedded'
函数的类型签名与ExceptT
类型构造函数进行比较:
ExceptT e m a
| | |
MaybeT (ExceptT String (ReaderT () IO) (**missing here**) ) Int
如何让ExceptT
更高级?
我也试过了:
fullType :: ExceptT String []
fullType = undefined
编译器抱怨:
* Expecting one more argument to `ExceptT String []'
Expected a type, but `ExceptT String []' has kind `* -> *'
* In the type signature:
fullType :: ExceptT String []
失败,模块加载:无。
答案 0 :(得分:3)
你可能会被最外面的MaybeT
弄糊涂了。此类型分别由种类m :: * -> *
和a :: *
的2个参数进行参数化。因此,ExceptT String (ReaderT () IO)
确实错过了a
,因为它是MaybeT
第一个参数,应该是* -> *
种类。如果我们将Int
应用于ExceptT
,它将变为*
,然后无法传递给MaybeT
。
答案 1 :(得分:0)
免责声明:我没有使用我的Haskell环境,所以这可能完全是胡说八道。
为ExceptT
上的缺失点添加显式类型变量:
embedded' :: MaybeT (ExceptT String (ReaderT () IO) a) Int
embedded' = MaybeT (ExceptT (ReaderT (const (return (Right (Just 1))))))
希望编译器能够找出a
应该是什么!
您在fullType
示例中更明显地显示的是,您无法提供某种类型* -> *
。函数,值等都需要有类型*
。
为一个类型构造函数提供一个* -> *
,所以你必须为所有参数提供某些东西。
在embedded'
的签名中添加一个类型参数使其变为*
,但多态性超过a
。