簡體   English   中英

對重載的數值操作使用“默認”聲明

[英]using “default” declaration for overloaded numeric operations

我嘗試在Haskell中開發嵌入式領域特定語言。 我不想一直將簽名鍵入為::Rational ,所以我嘗試為我的類型使用默認聲明:

Haskell報告中的相應部分

在以下簡單示例中,這可以正常工作:

default (Integer, Double) -- "default default"

mag :: Float -> Float -> Float
mag x y = sqrt( x^2 + y^2 )

main = do

print $ mag 1 1

實際上,我們獲得了sqrt(2)作為結果。 如果我們將默認聲明替換為:

default ()

,我們會按預期在編譯時獲得錯誤: 2的類型不明確。

現在讓我們考慮一個更復雜的示例:

{-# LANGUAGE FlexibleInstances #-}
import Prelude hiding ((^^))
import Data.Ratio

default (Integer, Rational, Double)

class (Num a) => Foo a where
    (^^) :: Num b => b -> a -> b

instance Foo Rational where
    (^^) x r = x ^ n
        where n = 2*numerator r -- dummy calculation

instance Foo Integer where
    (^^) x n = x ^ n

mag :: Float -> Float -> Float
mag x y = sqrt( x ^^ 2 + y ^^ 2 )

main = do
print $ mag 1 1

我希望它可以正常工作,但是我們會得到有關2的歧義類型的錯誤。 為什么? 如何使我的默認聲明生效? 如果我要優先考慮Rational而不是Integer 確實,這應該是可能的,因為下面沒有任何錯誤。

$ ghci
> import Data.Ratio
> 2::Rational
2 % 1

PS1:答案可能與

對堆棧溢出問題的答案

但我不知道用哪種方式。

PS2:一周前,我已經在Haskell-Cafe上問過這個問題:

http://www.haskell.org/pipermail/haskell-cafe/2013-September/108956.html

但是,由於我沒有得到答案,我在這里提出問題。

Haskell對於類型類默認設置非常保守:它僅選擇Prelude中定義的類的默認實例。 在您的情況下,文字2的類型存在Foo約束,因此編譯器不會為其選擇默認實例。

您可以通過編寫單態函數以語法上更輕松的方式聲明類型。 例如,以下編譯無錯誤:

rat :: Rational -> Rational
rat x = x

mag :: Float -> Float -> Float
mag x y = sqrt( x ^^ rat 2 + y ^^ rat 2 )

暫無
暫無

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

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