类型未完全应用

时间:2017-09-25 12:55:45

标签: haskell

我有以下来自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 []

失败,模块加载:无。

2 个答案:

答案 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