【问题标题】:Cannot implement Foldable instance due to wrong kind由于类型错误,无法实现可折叠实例
【发布时间】:2019-11-10 17:11:50
【问题描述】:

我正在学习 haskell 并尝试制作一个漂亮的打印程序。在某些时候,我想获得一行的长度(即该行中的列数)。为了能够在我的数据类型上做到这一点,我知道我必须实现可折叠,它依赖于 Monoid。

以前我的行只是列表的类型别名,但为了学习,我想这样做

    import System.IO
    import System.Directory
    import Control.Monad
    import Data.Maybe
    import Data.Monoid
    import Data.Foldable
    import Data.Functor
    import Data.List.Split

    type Field = String
    data Row = Row [Field]

    instance Monoid Row where
        mempty = Row []


    instance Foldable Row where
        foldMap f (Row fs) = foldMap f fs

但我收到以下编译器错误(在 ghci 8.0.2 上)

main.hs:20:19: error:
    • Expected kind ‘* -> *’, but ‘Row’ has kind ‘*’
    • In the first argument of ‘Foldable’, namely ‘Row’
      In the instance declaration for ‘Foldable Row’

现在我不熟悉数据类型的种类。我期待这只是简单地遵循 Row 的 List 类型的唯一属性

【问题讨论】:

    标签: haskell ghc foldable


    【解决方案1】:

    当我们有Foldable T时,T必须是参数类型,即我们必须能够形成T IntT String等类型。

    在 Haskell 中,我们写 T :: * -> * 表示“在类型上参数化的类型”,因为它类似于从类型到类型的函数。语法* -> * 称为T种类

    在您的情况下,Row 没有参数化,它是一个普通类型,类似于*,而不是* -> *。所以,Foldable Row 是一种错误。从某种意义上说,可折叠必须是 generic 类似列表的容器,而不是像您的情况那样只携带 Field 的容器。

    您可以改为定义data Row a = Row [a],并在需要特定情况时使用Row Field

    或者,您可以尝试mono-traversable 包中的MonoFoldable Row,但请注意,这是一个更高级的选项,涉及类型系列。在考虑其后果之前,不要掉以轻心。它最终归结为为什么你需要一个Foldable 实例。

    【讨论】:

    • @HugoPeters 使用来自Foldable 的标准length 和非参数化Row 这确实是不可能的。您可以声明一个不同的长度函数,但这需要有另一个名称(或在另一个包中,并手动消除两个长度函数之间的歧义)。例如MonoFoldable 提供olength 以避免名称冲突。
    【解决方案2】:

    什么是数据类型的“种类”

    类型“*”是可以出现在 Haskell 程序中的事物的类型

    例如:Int

    不是一个例子:Maybe

    a :: Int ; a = 1 可以出现在 Haskell 程序中,但 b :: Maybe ; b = Just 1 不能。它必须是b :: Maybe Int ; b = Just 1,才能有效地出现在 Haskell 程序中。

    Maybe Int 是什么?它是* 的一种类型,就像Int 一样。那么Maybe 是什么?它是一种类型* -> *。因为Maybe Maybe 无效。

    出现在Maybe 之后的类型t 本身必须是同类*,因为Maybe t 是同类*。因此Maybe 的类型是* -> *

    Haskell 现在用新名称 Type 调用类型 *。将其称为 Thing 或其他名称可能更直观。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-03-16
      相关资源
      最近更新 更多