Classy-Prelude(head。head)

时间:2014-02-25 22:51:58

标签: haskell classy-prelude

我正在尝试将多个项目转换为classy-prelude。虽然大多数行为对我来说都很简单,但(head . head)在简单的2D列表上给出了神秘的错误。

考虑以下GHCi会议:

Prelude> (head . head) [[1,2],[3,4]]
1

让我们试试ghci -XNoImplicitPreludeclassy-prelude

> import ClassyPrelude
ClassyPrelude> (head . head) [[1,2],[3,4]]

<interactive>:10:1:
    Couldn't match type `MinLen (Succ nat1) mono1' with `[[t0]]'
    Expected type: [[t0]] -> Element mono0
      Actual type: MinLen (Succ nat1) mono1 -> Element mono0
    The function `head . head' is applied to one argument,
    but its type `MinLen (Succ nat1) mono1 -> Element mono0'
    has only one
    In the expression: (head . head) [[1, 2], [3, 4]]
    In an equation for `it': it = (head . head) [[1, 2], [3, 4]]

我认为GHC根本无法正确解析多维列表的类型。有没有办法可以帮助它而不诉诸(Prelude.head . Prelude.head)

1 个答案:

答案 0 :(得分:11)

正如评论中已经提到的那样,优雅前奏的head函数仅适用于可以通过类型系统保留至少一个元素的遍历,因此它不必是部分的。因为您的所有列表至少有一个元素,所以您可以使用非空列表类型:

head . head $ mlcons (mlcons 1 $ mlcons 2 $ toMinLenZero []) $ mlcons (mlcons 3 $ mlcons 4 $ toMinLenZero []) $ toMinLenZero [] :: Int
-- 1

(以ml开头的函数全部来自mono-traversable的{​​{3}}模块,由classy-prelude重新导出

如果您只想要Prelude.head功能的行为,可以再次使用mono-traversable包中的MinLen并默认导出:

unsafeHead . unsafeHead [[1,2],[3,4]]
-- 1

该模块中还有headMay,如果您希望以不同方式处理故障并且不会导致整个程序崩溃,则可以使用该模块。