2015-11-14 59 views
0

在Haskell,我只知道,什麼是Haskell中的'(float a,Num(a - > a))'?

:type ((+)(1)) 
((+)(1)) :: Num a => a -> a 
((+)(1) 2 
3 

但如何

:type abs(sqrt) 
abs(sqrt) :: (Floating a, Num (a -> a)) => a -> a 

其實,我嘗試了很多次,但未能使用該功能 'ABS(開方)'。然後我有幾個問題。什麼是類型(班級?)'(浮動a,數字(a - > a))'?是否可以使用函數'abs(sqrt)'?怎麼樣?

+2

我投票結束這個問題作爲題外話,因爲它似乎你從來沒有打擾到檢查出基本介紹哈斯克爾。我真誠地想知道是什麼讓你認爲'abs(sqrt)'會起作用,什麼使你使用這種語法。 –

+1

@OtosakaYuu:它是'abs sqrt'而不是'abs(sqrt)' - 後者會誤導你和其他人; ((+1)(1))「相同,它實際上就是」((+)1)「(在'1'周圍沒有parens),並且運算符部分簡化爲」(1 +)「 。瞭解並遵守這些規則將導致對Haskell的更好理解,以及清晰,慣用,專業外觀的代碼。 –

回答

0

類型類是泛化函數的一種方式,以便它們可以是多態的,而其他類型可以爲它們自己的類型實現這些函數。以一個例子的類型類Show,它以簡化的形式看起來像

class Show a where 
    show :: a -> String 

這表示實現該Show類型類的任何類型的可以被轉換爲一個String(有用於更逼真的約束一些更復雜,但具有Show的點就是能夠將值轉換爲String s)。

在這種情況下,函數show具有完整類型Show a => a -> String

如果我們檢查功能sqrt,它的類型是

> :type sqrt 
sqrt :: Floating a => a -> a 

而對於abs

> :type abs 
abs :: Num b => b -> b 

如果你問GHCI的類型是什麼它會在兩種情況下使用類型變量a ,但我在abs的類型簽名中使用了b來明確這些是同名的不同類型變量,這有助於避免在下一步中出現混淆。

這些類型簽名意味着sqrt需要一個值,其類型實現了Floating類型類(使用:info Floating看到所有的成員),並返回相同類型的值,並且該abs函數採用其類型實現了Num值typeclass並返回相同類型的值。

表達式abs(show)等效解析爲abs sqrt,這意味着sqrt是傳遞給abs的第一個也是唯一的參數。但是,我們只是說abs取值爲Num類型,但sqrt是一個函數,而不是數字。爲什麼Haskell接受這個而不是抱怨?當我們使用類型簽名進行替換時,可以更清楚地看到原因。由於sqrt的類型是Floating a => a -> a,這必須與abs的類型簽名中的參數b相匹配,所以通過將b替換爲Floating a => a -> a,我們得到abs sqrt :: (Floating a, Num (a -> a)) => a -> a

Haskell實際上允許函數類型實現類型類型Num,你可以自己做,雖然它可能是荒謬的。然而,僅僅因爲某些東西似乎對GHC沒有意義,只要類型可以乾淨地解決,它就可以實現。

你不能真的使用這個功能,它只是沒有意義。對於任何a,沒有內置的Num (a -> a)實例,因此您必須定義自己的實例。你可以,但是,組成使用複合算.功能abssqrt

> :type abs . sqrt 
abs . sqrt :: Floating c => c -> c 

這有一定道理。此功能相當於這裏

myfunc x = abs (sqrt x) 

注意x首次應用於sqrt,然後將該計算的結果傳遞給abs,而不是sqrt傳遞函數abs

+0

非常感謝,我現在完全理解它。 Haskell類型非常有趣:) – OtosakaYuu

0

可能無法使用此功能。

什麼可能發生在這裏的是,該類型是說,abs(sqrt)有約束a的類型必須是類Floating(a -> a)的類型必須爲類Num的。換句話說,sqrt函數需要能夠被視爲一個數字。

不幸的是,sqrt是不是類Num類型,所以不會有任何輸入,將在這裏工作(不是說它會有意義的)。但是,GHCi的某些版本允許您獲得可能的類型。

看看Haskell type length + 1是否有類似的問題。

正如ErikR所說的,也許你的意思是寫abs . sqrt

+1

嘿,那個答案看起來很熟悉...... – bheklilr

+0

嗯,好的模板答案 – tangrs

+0

那個類似的問題幫了我很多,thx! – OtosakaYuu

1

當你看到Num (a -> a)這通常意味着你在某個地方犯了一個錯誤。

也許你真的想要:abs . sqrt其型號爲Floating c => c -> c - 即它是浮動類型(例如浮點型,雙精度型)到同一浮點類型的函數。

+0

我明白了。非常感謝你。 – OtosakaYuu

相關問題