2

我正在学习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 类型的唯一属性

4

2 回答 2

4

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

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

在您的情况下,Row不是参数化的,它是一种普通类型,某种类型的东西*,而不是* -> *. 所以,Foldable Row是一种错误。从某种意义上说,可折叠的必须是一个通用的类似列表的容器,而不是仅Field在您的情况下携带的容器。

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

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

于 2019-11-10T17:31:04.810 回答
0

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

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

示例:Int

不是一个例子:Maybe

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

是什么Maybe Int*它是 一种类型Int。那么是什么Maybe?它是 kind 的一种* -> *。因为Maybe Maybe也是无效的

t后面出现的类型Maybemust be of kind *for Maybe tto be of kind *。因此那种Maybe* -> *

*Haskell 现在用新名称来调用这种类型, Type. 调用它Thing或其他东西可能更直观。

于 2019-11-11T16:13:58.873 回答