2017-08-27 30 views
0

我有一个类型定义为这样:'x'被定义为'y',但编译器无法将'y'与'x'匹配,为什么?

data People = People [[String]]

和看起来像这样一个函数定义:

myFunction :: ([String], People) -> (Int, Int) -> People 
myFunction first_tuple second_tuple = filter (myPredicate (fst second_tuple) (fst first_tuple)) (snd first_tuple) 

这给了我下面的错误:

error: 
* Couldn't match expected type `[[String]]' 
       with actual type `People' 
* In the second argument of `filter', namely `(snd first_tuple)' 

这有我真的难倒,因为我试图尽可能明确与我的括号和People是明确的y定义为[[String]]。是什么导致这种情况,为什么是这种情况?

这里是myPredicate类型签名:

myPredicate :: Int -> [String] -> [String] -> Bool 
+2

请包括'myPredicate'的定义 - 现在你的代码也包含多个错误('MyFunction'应该是'myFunction'),如果你正在通过'[[String]]过滤'People',你需要通过应用构造函数将后者转换为'People'。 – epsilonhalbe

+6

'人'是用'[[String]]来定义的,但不同于'[[String]]',也不能互换。它绝对没有被定义为** ** [[String]]'。 –

+0

@epsilonhalbe我编辑了我的帖子以包含'MyPredicate'的类型定义。 – JavascriptLoser

回答

3

首先函数名以及变量名已经开始与小写字母。所以

  • MyFunction =>myFunction
  • MyPredicate =>myPredicate

正如你定义

myPredicate :: Int -> [String] -> [String] -> Bool 

myPredicate第三个参数应该是 [String],在这里提供一个 People时您使用该功能。 您可以使用此功能与filter :: (a -> Bool) -> [a] -> [a] - a是专门[String]这样的filter第二个参数必须是[[String]]但您提供People这是不同的东西。

现在,你必须在函数定义

myFunction :: ([String], People) -> (Int, Int) -> People 
myFunction (strs,People ps) (x,_) = filter (myPredicate x strs) ps 
  • 编写自定义filterPeople功能3个选项

    1. 变化data People..type People = [[String]]
    2. 使用模式匹配,其中

      filterPeople :: ([String] -> Bool) -> People -> People 
      
  • +0

    实际上,不是编译器抱怨的myPredicate,而是期望数组作为第二个参数的过滤函数。不过,我同意你提出的选择。 –

    +0

    @mlambrichs thx - 固定! – epsilonhalbe

    +0

    尝试'myFunction(strs,People ps)(a1,a2)= filter((myPredicate a1 strs)(state))'产生错误:*无法与Char类型[Char]匹配预期类型:[String ]实际类型:[[String]]' – JavascriptLoser

    3

    People根据[[String]]定义,但与[[String]]不相同也不可互换。

    数据类型声明创建一个与所有其他类型不同的类型。在这种简单的情况下,People可以被认为是包装和标记的[[String]]。你需要明确的包装和解包以便从People[[String]]并返回。

    简单地说,在包装操作的拼写People

    p = People [["Mary", "Smith"], ["John", "Starke"]] 
    

    和unnwrapping与模式匹配来完成:

    printPeople (People ppl) = print ppl 
    

    如果你想被定义为一些其他命名类型类型,使用类型声明:

    type People = [[String]] 
    

    在这种情况下,People[[String]]完全同义。

    相关问题