在Haskell中统一类型

时间:2013-06-17 13:16:00

标签: haskell types functional-programming unify

我对考试有点不满。我想通过手工应用统一算法来找出这两个函数的类型:

map map
(\x -> x >>= (\y -> y))

有人能指出我正确的方向吗?到目前为止我唯一能找到的资源是维基百科条目,由于抽象程度很高,它并没有真正帮助我。

问候并谢谢你。

2 个答案:

答案 0 :(得分:5)

我们先做第一个。

map :: (a -> b) -> [a] -> [b]

现在我们可以用两个不同的名称再次写它,为清楚起见:

map :: (c -> d) -> [c] -> [d]

现在我们将第二个替换为第一个参数,得到:

(a -> b) === (c -> d) -> ([c] -> [d]) (recall the associativity of (->))
a === (c -> d)
b === ([c] -> [d])

现在我们将这些类型分配替换为第一个签名的剩余部分,获取

map map :: [c -> d] -> [[c] -> [d]]

清除?

答案 1 :(得分:1)

map的类型为map :: (a -> b) -> [a] -> [b]。因此,map foo的类型是通过将[a] -> [b]a替换为可以从b类型派生的内容而从foo获得的。例如,如果foo :: t -> t,则替换a = t, b = t并获取[t] -> [t]。如果foo :: [t] -> Int,则获得[[t]] -> [Int]

在您的情况下,foomap)的类型为(x -> y) -> [x] -> [y]。您必须将该类型与a -> b统一,以找出ab必须替换的内容。 [请注意,函数箭头是右关联的,x -> y -> z = x -> (y -> z)。]

找到

的类型
\x -> x >>= (\y -> y)

使用已知类型的(>>=) :: Monad m => m a -> (a -> m b) -> m b。暂时忽略约束(Monad m =>)。

作为(>>=)的第一个参数,x必须包含m a类型,但尚未知道ma(>>=)的第二个参数是身份,

(\y -> y) :: t -> t

因此您必须将t -> ta -> m b统一起来。这会为您提供有关a的一些信息,即a = m b

这会产生x :: m (m b)(\x -> x >>= (\y -> y)) :: type_of_x -> type_of_rhs

最后记住暂时忘记的约束Monad m =>