[英]Typeclass instances for another typeclass in haskell
有沒有更簡潔的方法來編寫以下haskell代碼:
{-# LANGUAGE FlexibleInstances #-}
class Greetable g where
hi :: g -> String
-- Here i should list all instances of Num
instance Greetable Float where
hi s = "Hi number! " ++ show s
instance Greetable Int where
hi s = "Hi number! " ++ show s
instance Greetable Double where
hi s = "Hi number! " ++ show s
-- Etc.
-- Here is other stuff
instance Greetable String where
hi s = "Hi string! " ++ s
編輯:我希望hi
函數能夠解決Num
類的任何將來的實例。
有超原始的方式
{-# LANGUAGE CPP #-}
#define GREETABLE_NUM(n)\
instance Greetable(n) where { hi s = "Hi number! " ++ show s }
GREETABLE_NUM(Int)
GREETABLE_NUM(Double)
...
本質上,使用Template Haskell可以更好地完成相同的操作,但是AFAIK您將需要兩個模塊(一個用於定義宏,一個用於使用宏),這在這里可能是過大了。
也許更明智的解決方案是簡單地編寫
numberHi :: Show n => n -> String
numberHi s = "Hi number! " ++ show s
instance Greetable Int where hi = numberHi
instance Greetable Double where hi = numberHi
...
這是默認方法簽名的好用例。
{-# LANGUAGE DefaultSignatures #-}
class Greetable g where
hi :: g -> String
default hi :: Show g => g -> String
hi s = "Hi number! " ++ show s
instance Greetable Float
instance Greetable Int
instance Greetable Double
instance Greetable String where hi s = "Hi string! " ++ s
另一種方式是這樣的:
{-#LANGUAGE ScopedTypeVariables#-}
import Data.Typeable
hi :: (Show a, Typeable a) => a -> String
hi x
| typeOf x == typeOf (3 :: Int) = "Hi number!" ++ show x
| typeOf x == typeOf (3.4 :: Double) = "Hi number!" ++ show x
| typeOf x == typeOf ("abc" :: String) = "Hi string!" ++ show x
因此,所有其他答案的答案都非常好,這與編譯指示和其他功能都不是“正確的” Haskell,但實際上它確實滿足了我的需要:
{-# LANGUAGE UndecidableInstances, FlexibleInstances #-}
class Greetable g where
hi :: g -> String
-- Here i should list all instances of Num
instance {-# OVERLAPS #-} (Show n, Num n) => Greetable n where
hi s = "Hi number! " ++ show s
-- Here is other stuff
instance {-# OVERLAPPABLE #-} Greetable String where
hi s = "Hi string! " ++ s
然后在ghci中:
λ> hi 1
"Hi number! 1"
λ> hi "hello"
"Hi string! hello"
λ> hi (1::Float)
"Hi number! 1.0"
要進一步閱讀,請參閱重疊的實例
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.