haskell - 由于类型错误,无法实现可折叠实例
问题描述
我正在学习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 类型的唯一属性
解决方案
当我们有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
推荐阅读
- javascript - D3.js 版本 6:加载 TSV 并更改变量类型
- oracle - 在物化视图中更改字段 - oracle
- javascript - 以更清洁的方式将属性传递给此
- javascript - 如何修复在 Google Lighthouse 上无法抓取链接
- java - 如何通过Java将TimeStamp直接转换为秒
- azure - Azure B2C:socialIdpUserId(或 issuerUserId)声明的目的
- data-structures - 哪个是更好的循环与真正的方程
- python-3.x - 从现有句子中提取特定单词
- rust - 如何有效地找到 Rust 中 u64 整数的 2 的下一个幂?
- matlab - 从 .mat 文件中的结构中提取数据