假设我们有以下内容:
{-# LANGUAGE FlexibleInstances #-}
module Sample where
newtype A a =
A a
deriving (Show)
newtype L a =
L [a]
class ListContainer l where
getList :: l a -> [a]
instance ListContainer L where
getList (L l) = l
instance (Show a, ListContainer l) => Show (l a) where
show = const "example"
Run Code Online (Sandbox Code Playgroud)
使用此代码,ghc 抱怨:
warning: [-Wdeferred-type-errors]
• Overlapping instances for Show (A a)
arising from a use of ‘GHC.Show.$dmshowList’
Matching instances:
instance (Show a, ListContainer l) => …Run Code Online (Sandbox Code Playgroud) 在尝试使用数字前奏来定义一些数学对象时,我遇到了一个问题.Additive类型类定义了一个实例
instance Additive.C v => Additive.C [v]
Run Code Online (Sandbox Code Playgroud)
我读到"如果v是添加剂,[v]也是"(显然我在这里错了).它实现了类似的东西
(+) x y = map (\(a,b) -> a + b) $ zip x y
Run Code Online (Sandbox Code Playgroud)
所以[1,2,3] + [4,5,6] = [5,7,9]这对我想做的事情毫无用处.我以为我不会有问题,因为我的v类型不是Additive.不幸的是,我仍然遇到重叠的实例错误,我发现它很混乱.我做了一点阅读,我现在明白,由于某种原因,Haskell忽略了"=>"位之前的所有内容,所以我应该读取默认实例为"任何列表在默认实例的意义上都可能是附加的".我尝试使用OverlappingInstances,尽管这个扩展名称具有"危险",但即便如此也没有帮助.
这是我的测试用例.
{-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE MultiParamTypeClasses,FlexibleInstances #-}
{-# LANGUAGE OverlappingInstances #-} --This doesn't seem to help
import NumericPrelude
import qualified Algebra.Additive as Additive
data Test = Red | Green | Blue deriving Show
instance Additive.C [Test] where
zero = undefined
(+) = undefined
negate = undefined
test = [Red] + [Green] …Run Code Online (Sandbox Code Playgroud) 如果我可以将Monads视为Nums(当然适用的话),我会有一些代码更清晰.足够轻松完成:
{-# 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 …Run Code Online (Sandbox Code Playgroud) 我有一个类型类:
class Wrapper w where
open :: w -> Map String Int
close :: Map String Int -> w
Run Code Online (Sandbox Code Playgroud)
它看起来并不是很有用,但是我用它强烈地(不仅仅是一个type同义词)来区分语义上不同的Map String Ints:
newtype FlapMap = Flap (Map String Int)
newtype SnapMap = Snap (Map String Int)
...
Run Code Online (Sandbox Code Playgroud)
并且仍然具有可在任何类型的类上运行的函数.
Wrapper实例样板)?我想做这个:
instance (Wrapper wrapper) => Show wrapper where
show w = show $ toList $ open w
Run Code Online (Sandbox Code Playgroud)
而不是编写许多样板Show实例.
通过FlexibleInstances和UndecidableInstances,GHC引导我到一个点,它认为我的实例声明适用于所有内容,因为它据称与Show我的代码中的其他实例冲突GHC.Show.HaskellWiki和StackOverflow的回答者和HaskellWiki说服我OverlappingInstances不太安全,可能会让人困惑.GHC甚至没有建议.
为什么GHC首先抱怨不知道Show Int要选择哪个fx实例(为什么它不查看我在编译时给出的约束?)然后,被告知实例可能重叠,突然知道该怎么做? …