【问题标题】:Unifying Types in Haskell在 Haskell 中统一类型
【发布时间】:2013-06-13 10:59:31
【问题描述】:

我有点纠结于我的考试作业。我想通过手动应用统一算法找出这两个函数的类型:

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

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

您好,谢谢。

【问题讨论】:

标签: haskell types functional-programming unify


【解决方案1】:

我们只做第一个。

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]]

清除?

【讨论】:

  • 我认为他们通常也要求对类型统一进行解释。
  • 非常感谢。这个解释正是我正在寻找的。这是我一直错过的右联想。很棒的帖子。
【解决方案2】:

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

在您的情况下,foo(即map)的类型是(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 =>

【讨论】:

  • 谢谢你的回答澄清了这一点。非常感谢您投入的时间。
猜你喜欢
  • 1970-01-01
  • 2012-06-29
  • 1970-01-01
  • 1970-01-01
  • 2011-07-11
  • 2011-10-27
  • 1970-01-01
  • 1970-01-01
  • 2017-08-13
相关资源
最近更新 更多