Haskell - 为什么它有正确的类型?

时间:2016-04-11 20:50:09

标签: haskell monads

我对输入正确的事实感到失望:

renumberTree2' :: Tree a -> StateT Int Identity (Tree Int)
renumberTree2' t = get >>= (\v -> return (Empty))

毕竟,我们有:
(>>=) :: m a -> (a -> m b) -> m b。由于StateT s m a我们无法绑定get :: StateT s m s这一事实。 get不是m a类型的预期bind 但是,get s其中s :: s->(a, s')是正确的类型,应该给予绑定。我哪里错了?

3 个答案:

答案 0 :(得分:6)

你在阅读类型时错了。您可以像处理优先级的函数一样处理更高级的kinded类型(具有类型参数的类型)。如果你有一个功能

f :: a -> b -> c -> d -> e
f a b c d = undefined

然后调用它

let e = f a b c d

相当于

let e = (((f a) b) c) d

f a :: b -> c -> d -> e以及(f a) b等等

当您看到类型StateT s m a时,您也可以将其视为((StateT s) m) a,类型是等效的,GHC会乐意接受该语法。通过这种方式,可以更轻松地了解Monad m => StateT s m aMonad m' => m' a'的对齐方式:

m' ~ StateT s m
a' ~ a

这意味着有问题的Monad m'StateT s m。一个更简单的示例以完全相同的方式工作,是Functor的{​​{1}}实例。 Either a实例不是Either,而是Functor,因为Either a是类型为Functor的类型,这意味着只有* -> *类型一种类型的参数。

答案 1 :(得分:2)

  

毕竟,我们有:(>>=) :: m a -> (a -> m b) -> m b

> :type (>>=)
(>>=) :: Monad m => m a -> (a -> m b) -> m b

真。

  

get不符合预期[{1}}类型[by] bind。

m a

不,> import Control.Monad.State > :type get get :: MonadState s m => m s 属于get类型(虽然它确实带有约束)。

答案 2 :(得分:1)

get的类型为m s,其中s是州类型。 MonadState的{​​{1}}实例具有上下文:

StateT

所以monad类型Monad m => MonadState s (StateT s m) m。因此,StateT s m的{​​{1}}类型为:

get

StateT的函数必须为某些结果类型(StateT s m) s 添加(>>=)类型。

s -> StateT s m b
由于b是monad,

的类型为return (Empty)