Monad
如果我可以将s 视为Num
s(当然,在适用的情况下),我有一些代码会写得更干净。很容易做到:
{-# LANGUAGE FlexibleInstances #-}
import Control.Monad (liftM, liftM2)
import Data.Char (digitToInt)
instance (Monad m, Num a) => Num (m a) where
(+) = liftM2 (+)
(-) = liftM2 (-)
(*) = liftM2 (*)
abs = liftM abs
signum = liftM signum
fromInteger = return . fromInteger
square :: (Monad m, Num a) => m a -> m a
square x = x * x
-- Prints "Just 9", as expected
main = putStrLn $ show $ square $ Just 3
但是当我将以下函数添加到文件中时......
digitToNum :: (Num a) => Char -> a
digitToNum = fromIntegral . digitToInt
…我收到以下错误:
monadNumTest.hs:15:14:
Overlapping instances for Num (m a)
arising from a use of `*'
Matching instances:
instance (Monad m, Num a) => Num (m a)
-- Defined at monadNumTest.hs:6:10
instance Integral a => Num (GHC.Real.Ratio a)
-- Defined in `GHC.Real'
(The choice depends on the instantiation of `m, a'
To pick the first instance above, use -XIncoherentInstances
when compiling the other instance declarations)
In the expression: x * x
In an equation for `square': square x = x * x
这对我来说没有意义,因为 (1)digitToNum
从未被调用, (2)Ratio
不是Monad
. 所以我不确定这是如何或为什么会出现问题。任何有关此的提示将不胜感激。
这是 GHC 7.4.2,使用 Haskell 平台 2012.4.0.0。