2012-07-26 160 views
4

我有以下的功能就像一個索引操作:Haskell中的Just是什麼?爲什麼沒有它,這個函數不能工作?

let { 
    index :: [a]->Int->Maybe a 
    index [] i = error "Empty list" 
    index l i = if i <= ((length l) - 1) && i >= 0 then 
     Just(l !! i) 
    else 
     error "Index out of bounds" 
} 

現在,我開始寫這不使用Just(和我還是不明白什麼是谷歌搜索後):

let { 
    index :: [a]->Int->Maybe a 
    index [] i = error "Empty list" 
    index l i = if i <= ((length l) - 1) && i >= 0 then 
     (l !! i) 
    else 
     error "Index out of bounds" 
} 

對我而言,上述功能非常有意義。因爲這裏我有一個函數,它接受'通用類型'aInt這是索引並返回Maybea的值或拋出運行時異常。但是,我不明白的地方GHCI告訴我這個位:

<interactive>:1:120: 
Couldn't match type `a' with `Maybe a' 
    `a' is a rigid type variable bound by 
     the type signature for index :: [a] -> Int -> Maybe a 
     at <interactive>:1:34 
Expected type: [Maybe a] 
    Actual type: [a] 
In the first argument of `(!!)', namely `l' 
In the expression: (l !! i) 

現在,爲什麼GHCI感到困惑與l類型,爲什麼它期待Maybe a類型的列表?最後,Just如何解決問題?

+1

代碼大師,現在我的代碼在你編輯後看起來很舒服:) – badmaash 2012-07-26 21:03:56

+0

你真的喜歡用你最初發布的單行代碼寫你的定義嗎? – gspr 2012-07-26 21:04:34

+1

其實,我絕對不會寫這樣的單行,因爲我來自C++/VB.NET背景。由於Haskell爲我提供了選擇編寫 - 編譯 - 執行還是隻寫執行的選項,我的懶惰更喜歡第二種選擇。另外,我剛開始學習它,所以只有'玩具程序'會這樣寫。也許我不知道我是否可以在GHCi的多行中分割我的代碼,是嗎? – badmaash 2012-07-26 21:12:06

回答

6

您已在類型註釋中明確指出您的函數index返回Maybe a

也許是在Haskell正是如此定義的數據類型:

data Maybe a = Just a | Nothing 

即,它有兩個值構造,Just :: a -> Maybe aNothing :: Maybe a。因此,爲了使您的功能正常工作,它必須返回Just aNothing

這也意味着你應該能夠通過一些想法去除你的錯誤陳述並且編碼Nothing中的實際錯誤(即,我們超出了界限,這裏沒有元素!)並且僅返回結果Just a如果它是有道理的。

+2

爲了保持對稱性,在「Nothing :: Maybe a」而不是「Nothing」關於構造函數的句子,因爲你已經給出了'Just'的類型,以防OP認爲它們是不同的野獸。 – gspr 2012-07-26 20:54:50

+1

@gspr:你顯然是對的!固定。 – Sarah 2012-07-26 21:02:07

+0

對,我會讀更多關於價值ctors,數據類型和類型的...我認爲Haskell會成爲一個歡樂騎...... :) – badmaash 2012-07-26 21:18:11

1

從文檔,Data.Maybe

的也許類型封裝了一個可選值。類型Maybe的值可以包含a類型的值(表示爲Just a),或者爲空(表示爲Nothing)。

如果你正在尋找一個類型Maybe Int那麼你的函數將返回Nothing,或Just Int

這是一種簡單的錯誤monad,其中所有錯誤都由Nothing表示。

本質上,如果Nothing返回,然後發生了一些事情導致函數無法找到結果。 Just限定符允許您使用這些Maybe類型。

1

您告訴GHC返回類型indexMaybe a。這意味着(l !! i)(由index返回的值)必須是Maybe a

由於(l !! i)被選擇單個元件出名單l的,這意味着l必須按順序[Maybe a]類型的其元件中的一個是Maybe a

lindex的第一個參數,您也告訴GHC鍵入[a]

這正是你的錯誤。 GHC正試圖編制一個索引到[Maybe a]得到一個Maybe a,但它被發現被索引的東西是[a]

原因Just修復此問題,是Justa -> Maybe a類型。所以,當你說Just (l !! i)時,GHC現在看到你索引[a]得到a,然後將Just應用到導致Maybe a的那個,如預期的那樣。

相關問題