我有一个函数,Num取决于它是浮点数,双精度还是整数取一个并做不同的事情.我发现这样做的唯一方法是使用类型类,但这看起来非常难看.有没有办法匹配任何类型的数字,所以做不同的事情取决于3个Num实例中的哪一个?就像是
myFun :: (Num a) => a -> T
myFun n = case n of
n :: Int -> something for ints
n :: Float -> something for floats
n :: Double -> something for doubles
Run Code Online (Sandbox Code Playgroud)
而不是
class MyClass a where
myFun :: (Num a) => a -> T
Run Code Online (Sandbox Code Playgroud)
与实例Int,Float,Double?
根据我的阅读,这是类型类的教科书应用程序:
module Main where
class Num a => Funnable a where
myFun :: a -> a
instance Funnable Int where
myFun = id
instance Funnable Float where
myFun = (+ 2)
instance Funnable Double where
myFun = (+ 1)
main :: IO ()
main = do
print $ myFun (1 :: Int)
print $ myFun (1 :: Float)
print $ myFun (1 :: Double)
Run Code Online (Sandbox Code Playgroud)
得到:
$ stack exec example
1
3.0
2.0
Run Code Online (Sandbox Code Playgroud)
如果使用不正确,类型类也会为您提供编译时类型错误.例如,假设我们跳过了实例声明Double:
src/Main.hs:14:13: error:
• No instance for (Funnable Double) arising from a use of ‘myFun’
• In the second argument of ‘($)’, namely ‘myFun (1 :: Double)’
In a stmt of a 'do' block: print $ myFun (1 :: Double)
In the expression: do { print $ myFun (1 :: Double) }
Run Code Online (Sandbox Code Playgroud)
你可以建模这样的东西:
data MyNum
= MDouble Double
| MInt Int
| MFloat Float
deriving (Show,Eq,Ord)
handle :: MyNum -> IO ()
handle (MDouble x) = putStrLn "This is double"
handle (MFloat x) = putStrLn "This is float"
handle (MInt x) = putStrLn "This is int"
Run Code Online (Sandbox Code Playgroud)
实际上,在库bson中使用了类似的抽象类型来建模它的Value类型.