簡體   English   中英

Haskell中另一個類型類的類型類實例

[英]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.

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