我有以下代碼:無法理解,爲什麼MonoFoldable爲我喜歡的類型不編譯或錯誤消息
{-# LANGUAGE NoImplicitPrelude, OverloadedStrings, TypeFamilies #-}
module AI.Analysis.Rules where
import ClassyPrelude
-- Our set of rules
data RuleSet a = RuleSet [Rule a] [Rule a]
deriving (Eq)
mkRuleSet :: (Ord a) => [Rule a] -> RuleSet a
mkRuleSet rules = uncurry RuleSet (partition isStandard uniques)
where uniques = ordNub rules
isStandard x = case x of
Standard _ _ -> True
LastResort _ -> False
instance (Show a) => Show (RuleSet a) where
show (RuleSet s l) = unlines [toLines s, "----", toLines l]
where toLines = unlines . fmap show
instance (Ord a) => Monoid (RuleSet a) where
mempty = RuleSet [] []
mappend (RuleSet s1 l1) (RuleSet s2 l2) = RuleSet (ordNub (s1 ++ s2)) (ordNub (l1 ++ l2))
instance (Ord a) => Semigroup (RuleSet a) where
(<>) = mappend
type instance Element (RuleSet a) = (Rule a)
instance MonoFoldable (RuleSet a) --this is unhappy
-- A rule in our system
-- For now, we assume rules *individually* are always internally-consistent
data Rule a = Standard [a] a | LastResort a
deriving (Eq)
mkRule :: (Eq a, Ord a) => [a] -> a -> Rule a
mkRule as c = case as of
[] -> LastResort c
_ -> Standard ((sort . ordNub) as) c
-- Last-resort rules and standard rules cannot be compared for consistency
mutuallyConsistent :: (Eq a) => Rule a -> Rule a -> Maybe Bool
mutuallyConsistent (LastResort c1) (LastResort c2) = Just (c1 == c2)
mutuallyConsistent (Standard as1 c1) (Standard as2 c2) = Just ((as1 /= as2) || (c1 == c2))
mutuallyConsistent _ _ = Nothing
instance (Show a) => Show (Rule a) where
show x = case x of
Standard as c -> formatAnd as ++ " -> " ++ show c
LastResort c -> "-> " ++ show c
where formatAnd = unwords . intersperse "^" . map show . otoList
-- LastResort rules are always ordered smaller than standard ones
instance (Ord a) => Ord (Rule a) where
(<=) (LastResort _) (Standard _ _) = True
(<=) (Standard _ _) (LastResort _) = False
(<=) (LastResort c1) (LastResort c2) = c1 <= c2
(<=) (Standard as1 c1) (Standard as2 c2) = (as1 <= as2) || (c1 <= c2)
不過,我從編譯器,我無法理解其含義如下錯誤:
/home/koz/documents/uni/research/summer-research-2015/clinical/rules-analysis/src/AI/Analysis/Rules.hs:47:10:
Couldn't match type ‘a’ with ‘Rule a’
‘a’ is a rigid type variable bound by
the instance declaration
at /home/koz/documents/uni/research/summer-research-2015/clinical/rules-analysis/src/AI/Analysis/Rules.hs:47:10
Expected type: Element (RuleSet a)
Actual type: a
Relevant bindings include
ofoldMap :: (Element (RuleSet a) -> m) -> RuleSet a -> m
(bound at /home/koz/documents/uni/research/summer-research-2015/clinical/rules-analysis/src/AI/Analysis/Rules.hs:47:10)
In the expression:
mono-traversable-0.10.0.1:Data.MonoTraversable.$gdmofoldMap
In an equation for ‘ofoldMap’:
ofoldMap
= mono-traversable-0.10.0.1:Data.MonoTraversable.$gdmofoldMap
In the instance declaration for ‘MonoFoldable (RuleSet a)’
近,我可以告訴我的想法似乎是有道理的 - 畢竟,一個RuleSet
僅僅是Rule
s,這應該允許可摺疊的容器,但有問題的錯誤報文不會使對我來說任何意義。有人能澄清我在這裏沒有把握什麼嗎?
謝謝你 - 這個類型沒有描述'最小實現',我真的不確定實際需要或不需要。 另外,爲什麼你現在知道你永遠不會使用優雅的前奏?這可以在上游解決嗎? –
@KozRoss我喜歡前奏中的一些權力,但最終的前奏應該是原則性的,而且很簡單。即使我們現在在GHC中使用了相當大的默認Prelude,其原理也很清晰,並沒有使用特別複雜的功能 - 種類,MPTC,TypeFamilies都在其他地方。它不依賴於大量的庫或大量的數據類型,某些作者可能認爲它應該是該語言的一部分。 –
這是一個愚蠢的結論,因爲有可用的功能的默認實現。默認實現可用於解決多態容器(如列表和向量)的常見情況,並且需要重寫否則。我無法想出任何你認爲這不符合這種(非常標準)違約使用原則的設計。 –