【问题标题】:Work with custom data type haskell使用自定义数据类型 haskell
【发布时间】:2016-11-24 10:59:32
【问题描述】:

我有这个数据类型data List x = LT [(x,[String])] 我一直在尝试创建一个函数,该函数将向List 添加一个新元素。

例如通过使用函数add:

add ('a', ["1","2"]) [('x',["1"])]

结果是:

[('x',["1"]), ('a', ["1","2"])]

顺序是什么并不重要。 试了很多,还是不太明白。

这是我尝试过的

`add:: Ord a => a -> List a -> List a 
 add _ (LT[]) = empty 
 add x (LT(y:ys))
     | belongs x (LT(y:ys)) = (LT(y:ys)) 
     | otherwise = (LT(y:ys)) ++ (LT(x))`

有人可以帮忙吗? 提前致谢。

【问题讨论】:

  • 你不能只用++吗?您已经在定义中使用了 Haskell 列表,因此如果您将 ('a', ["1","2"]) 作为列表提供,例如[('a', ["1","2"])],那么您的函数可以只获取两个列表,使用 ++,并返回一个包含两者的新列表。 hackage.haskell.org/package/base-4.9.0.0/docs/Data-List.html
  • @DannyWilson,抱歉,我可能没有正确地提出问题,add 函数接收元素和列表(LT),而不是完全的元组和列表,所以 ++ 不起作用。
  • 你的例子应该是add 'a' [('x', ["1"])]。不过,尚不清楚结果中应该与'a' 关联的列表。它只是与前一个最后一个值关联的相同列表,但在末尾添加了一个数字转换字符串吗?

标签: haskell custom-data-type


【解决方案1】:

正如 Danny Wilson 指出的,您可以使用 ++ 运算符连接两个列表:

ghci> [1,2] ++ [3,4]
[1,2,3,4]

请记住,++ 的两边都必须是列表,并且您有一个列表和一个非列表,因此您需要先将其中一个放入列表。

根据您措辞中的一些细节,我有一个疯狂的猜测,即您在使用数据构造函数时遇到了问题。 List x 不采用这种形式

[('x',["1"])]

而是

LT [('x',["1"])]

这只是一个用LT 构造函数“包装”的常规列表。如果你想写一个函数add,你需要在这个构造函数上进行模式匹配。 List 类型的每个值都“以”LT 开头:

add :: (x, [String]) -> List x -> List x
add elem (LT list) = LT (...)

(需要自己填写...

你只需要在需要访问类型的胆量时,把LT放在里面,列表里面。所以这个函数返回未修改的列表,它不需要LT

doNothing :: List x -> List x
doNothing a = a

但是,一旦您需要知道 List x 由一些东西的列表表示,您就需要使用 LT 构造函数。

这有帮助吗?

【讨论】:

  • 有点,这是我尝试做的add:: Ord a => a -> List a -> List a add _ (LT[]) = empty add x (LT(y:ys)) | belongs x (LT(y:ys)) = (LT(y:ys)) | otherwise = (LT(y:ys)) ++ (LT(x)) 但它不起作用(belongsempty 是我做了两个函数)。
  • 是的,LT(x) 存在类型错误,因为 x 不是列表。试试LT [x](先把它变成一个单元素列表,我们从不需要括号)。请注意,这是指定的方式,将某些内容添加到空列表将始终为空,这...看起来不太正确。但你的首要目标应该是让它编译时不会出现类型错误。
  • 哦,当您说(LT ...) ++ (LT ...) 时,还有另一个类型错误。 ++ 需要两个 haskell 列表,而不是你的两个 Lists(由 LT 创建)。您需要将++ inside 放在LT 构造函数中。
  • 喜欢这个(LT (y:ys) ++ x)??
  • 只是为了澄清一下,您的数据类型和类型签名是非常不同的东西。您的数据类型是data List x = LT [(x,[String])],它定义了您要处理的数据,有点像OO 中的对象。可以这样想,你有数据类型data Circle = Float Float Float,它定义了一个带有 3 个浮点值的圆。然后,当您希望对其进行操作时,您编写一个函数。第一行是类型定义。因此,例如,addInts :: Int -> Int -> Int,它接受两个 int 并返回一个 Int。如果您不确定类型,请忽略此行...
猜你喜欢
  • 2011-12-20
  • 1970-01-01
  • 1970-01-01
  • 2021-12-28
  • 2012-03-12
  • 1970-01-01
  • 2014-08-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多