簡體   English   中英

具有不同類型的Haskell類型簽名

[英]Haskell type signatures with different types

我正在嘗試創建一個接受項列表並返回以下列表的函數:A)如果項“ X”連續出現兩次,則形式為(2,“ X”)的元組,或者返回B)項本身。它不與重復項相鄰。

例:

encode ["A", "A", "A", "B", "C", "C", "B", "B", "B", "D"]
> [(3, "A"), "B", (2, "C"), (3, "B"), "D"]

適當的類型簽名是什么? 我已經試過了:

data listItem a = (Integer, a) | a
encode :: (Eq a) => [a] -> [listItem a]

但是我得到這個錯誤:

parse error in constructor in data/newtype declaration: (Integer, a) 

我偷看了這個問題的解決方案,這給了我這種類型簽名:

data ListItem a = Single a | Multiple Int a
    deriving (Show)
encode :: Eq a => [a] -> [ListItem a]

但是當使用這個簡單的測試時

encode [x] = [x]

我收到一個錯誤:

Could not deduce (a ~ ListItem a)
from the context (Eq a)
  bound by the type signature for
             encode :: Eq a => [a] -> [ListItem a]
  at 99problems.hs:117:19-45
  `a' is a rigid type variable bound by
      the type signature for
        encode :: Eq a => [a] -> [ListItem a]
      at 99problems.hs:117:19
In the expression: x
In the expression: [x]

此問題的正確類型簽名是什么?

據我了解,“ 99個問題”集最初是為Prolog編寫的,然后翻譯為Lisp。 那時……啊……音譯成Haskell。 不幸的是,在Lisp中有意義的事情在Haskell中並不總是那么有意義,因此,從字面上看問題描述會給您帶來麻煩。 提示告訴您的是,與其嘗試編寫一個產生像[(3, "A"), "B", (2, "C"), (3, "B"), "D"] ,這在Haskell中根本是不可能的,您應該以生成類似[Multiple 3 "A", Single "B", Multiple 2 "C", Multiple 3 "B", Single "D"]

建議的類型簽名正確; 您只需要編寫與之匹配的代碼即可。

注意

就像我說的那樣,“ 99個問題集”並不是很像Haskellian。 它不尊重的Haskell代碼通常慣用的風格可言 ,所以你應該把它作為如何編寫Haskell代碼的典范。 例如,Haskell程序員(或者,理智的Lisp程序員)可能只會生成(Int,a)對的列表,而不會打擾那種使所有事情變得更加復雜,不那么統一的廢話。並且在實際應用中很可能會變慢。

“ 99問題”的其他幾種方式往往會破壞Haskell編程的通常期望:

  1. 它傾向於將參數置於與Haskell程序員不同的順序。 如果一個函數接受一個列表和一個數字,Haskell程序員幾乎總是將數字放在第一位,列表放在第二位; “ 99問題”趨向於相反。

  2. Haskell程序員幾乎總是對列表,數組等使用基於0的索引。“ 99問題”似乎喜歡基於1的索引。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM