2017-08-27 54 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]]完全同義。

    相關問題