简体   繁体   English

Haskell数据类型困境

[英]Haskell data type dilemma

Hey everyone I am working on a piece of Haskell code and cannot figure out how to fix this problem. 大家好,我正在编写一段Haskell代码,无法弄清楚如何解决此问题。

I get this error: 我收到此错误:

Couldn't match expected type `Collection' with actual type `[a0]'
In the expression: [list] ++ numberToInsert
In an equation for `insert':
    insert numberToInsert (Set [list])
      | contains (Set [list]) numberToInsert == True = (Set [list])
      | otherwise = [list] ++ numberToInsert

Failed, modules loaded: none. 失败,模块已加载:无。

Here is my code 这是我的代码

data Collection = Set [Int] deriving (Show)


insert :: Int -> Collection -> Collection
insert numberToInsert (Set [list])
    |contains (Set [list]) numberToInsert == True = (Set [list])
    |otherwise = [list] ++ numberToInsert  <--- this is my problem

contains :: Collection -> Int -> Bool
contains (Set []) numberToFind = False
contains (Set (x:xs)) numberToFind
    |x == numberToFind = True
    |otherwise = contains (Set (xs)) numberToFind

Can someone help me fix this? 有人可以帮我解决这个问题吗?

Thanks 谢谢

It appears you have two issues with your insert function. 看来insert功能有两个问题。

First, your two definitions of the insert function return different things. 首先,您对insert函数的两个定义返回不同的结果。

Set [list]   -- Return type here is Collection

and

[list] ++ numberToInsert  -- Return type here is some sort of list, or [a0]

So first, you'll need to Make the second version return a Collection : 因此,首先,您需要使第二个版本返回Collection

Set ([list] ++ numberToInsert)

But this is still wrong, because numberToInsert is not a list, and ++ concatenates two lists together, so I think you're really wanting to push it onto the front of your [list] . 但这仍然是错误的,因为numberToInsert不是列表,并且++将两个列表连接在一起,所以我认为您真的想将其推到[list]的前面。 : is used to push some a onto the front of a list of as Like so: :用于将a推送到Like列表的前面, as

Set (numberToInsert:[list])

Finished product: 完成的产品:

insert :: Int -> Collection -> Collection
insert numberToInsert (Set [list])
    | contains (Set [list]) numberToInsert == True = (Set [list])
    | otherwise = Set (numberToInsert : [list])

Update 更新资料

As you mentioned, there is one other issue I'd missed. 正如您提到的,我还错过了另一个问题。 list shouldn't be wrapped in the square brackets, and here's why (in case you hadn't figured it out). list不应该放在方括号中,这就是为什么(如果您还没有弄清楚的话)。

When you use the square brackets in a pattern match (the left side of the = ), you're saying: "give me a list that looks like this, and bind it's only item to some name for use later". 当您在模式匹配项( =的左侧)中使用方括号时,您的意思是:“给我一个看起来像这样的列表,并将其唯一的项目绑定到某个名称,以备后用”。 So you were only expecting a list with one item, and decided to call that item list . 所以,你只期待一个单个项目的列表,并决定把该项目list

Next, you repackaged up that one item in the new list when you used it as [list] . 接下来,当您将其用作[list]时,将其重新打包到新列表中。

this example: 这个例子:

foo [a] = a
main = print $ foo [1]

would print '1'. 将打印“ 1”。 Passing a list of two items, however, would fail to pattern match, because you had no foo [a, b] = ... function defined, hence the warning: 但是,传递两个项目的列表将无法进行模式匹配,因为您没有定义foo [a, b] = ...函数,因此出现警告:

main = print $ foo [1, 2]

So yes, removing all of the square brackets works because you are not requiring the list have only one item, but instead saying "the entire list will be called list ", which is probably what you wanted in the first place. 所以是的,删除所有方括号是可行的,因为您不需要列表只有一个项目,而是说“整个列表将被称为list ”,这可能就是您首先要的。

Here ya go. 你去。

import Data.List (elem)

data Collection = Set [Int] deriving (Show)

insert :: Int -> Collection -> Collection
insert numberToInsert c@(Set list)
  | numberToInsert `elem` list = c
  | otherwise = Set (numberToInsert:list)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM