我覺得這一定是整潔,允許在Haskell任意鏈接比較,所以你可以做一些簡單的檢查範圍,如:哈斯克爾:鼓勵GHC來推斷正確的中間類型
x <= y < z
而像
更復雜的東西x /= y < z == a
當上述兩者是語義上等同於
x <= y && y < z
x /= y && y < z && z == a
只是看到我f我可以使用語法。
所以我大部分的使用有幾個類型類的方式:
{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances #-}
module ChainedOrd where
import Prelude hiding ((<), (<=), (>), (>=), (==), (/=))
class Booly v a where
truthy :: v -> a
falsy :: v -> a
instance Booly a Bool where
truthy = const True
falsy = const False
instance Booly a (Maybe a) where
truthy = Just
falsy = const Nothing
class ChainedOrd a b where
(<),(>),(<=),(>=),(==),(/=) :: (Booly b c) => a -> b -> c
infixl 4 <
infixl 4 >
infixl 4 <=
infixl 4 >=
infixl 4 ==
infixl 4 /=
instance Ord a => ChainedOrd a a where
x < y = case compare x y of LT -> truthy y ; _ -> falsy y
x > y = case compare x y of GT -> truthy y ; _ -> falsy y
x <= y = case compare x y of GT -> falsy y ; _ -> truthy y
x >= y = case compare x y of LT -> falsy y ; _ -> truthy y
x == y = case compare x y of EQ -> truthy y ; _ -> falsy y
x /= y = case compare x y of EQ -> falsy y ; _ -> truthy y
instance Ord a => ChainedOrd (Maybe a) a where
Just x < y = case compare x y of LT -> truthy y ; _ -> falsy y
Nothing < y = falsy y
Just x > y = case compare x y of GT -> truthy y ; _ -> falsy y
Nothing > y = falsy y
Just x <= y = case compare x y of GT -> falsy y ; _ -> truthy y
Nothing <= y = falsy y
Just x >= y = case compare x y of LT -> falsy y ; _ -> truthy y
Nothing >= y = falsy y
Just x == y = case compare x y of EQ -> truthy y ; _ -> falsy y
Nothing == y = falsy y
Just x /= y = case compare x y of EQ -> falsy y ; _ -> truthy y
Nothing /= y = falsy y
哪個編譯罰款,但並不完全似乎允許鏈接,由於中間類型的問題。
-- works
checkRange1 :: Ord a => a -> a -> a -> Bool
checkRange1 x y z = x `lem` y <= z
where lem :: Ord a => a -> a -> Maybe a
lem = (<=)
-- works
checkRange2 :: Ord a => a -> a -> a -> Bool
checkRange2 x y z = (x <= y) `leb` z
where leb :: Ord a => Maybe a -> a -> Bool
leb = (<=)
checkRange1
和checkRange2
工作精細的,因爲它們既把一個約束在中間類型( 作爲第一比較,或者作爲一個參數到所述第二的結果)。
-- error
checkRange3 :: Ord a => a -> a -> a -> Bool
checkRange3 x y z = (x <= y) <= z
當我試圖讓編譯器推斷中間類型,但是,它又喊又叫。
ChainedOrd.hs:64:30:
Ambiguous type variable `a0' in the constraints:
(ChainedOrd a0 a) arising from a use of `<='
at ChainedOrd.hs:64:30-31
(Booly a a0) arising from a use of `<=' at ChainedOrd.hs:64:24-25
Probable fix: add a type signature that fixes these type variable(s)
In the expression: (x <= y) <= z
In an equation for `checkRange3': checkRange3 x y z = (x <= y) <= z
有沒有什麼辦法可以說服它應該使用Maybe a
作爲 中間型a0
satisifying Booly a a0, ChainedOrd a0 a
編譯器,因爲這是它知道的唯一實例?
失敗了,有沒有另一種方法可以讓任意比較鏈接工作?
當你閱讀[這個問題]你有沒有想法(http://stackoverflow.com/questions/9284350/why-does-1-in-1-0-true-evaluate-to-false)?當我閱讀它時,我認爲這個功能是多麼有用,但是在Python無法提供的漂亮的靜態類型輸入中卻很危險。可惜在Haskell中它的工作方式並不像它的類型系統那麼好,它確實提供了這種安全性。 – leftaroundabout 2012-02-20 02:39:37
@leftaroundabout其實,我從[本手冊中爲Julia語言]中得到了它(http://julialang.org/manual/mathematical-operations/#Numeric+Comparisons) – rampion 2012-02-20 04:19:42