首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >无法理解为什么我的类型的MonoFoldable不编译,或者错误消息

无法理解为什么我的类型的MonoFoldable不编译,或者错误消息
EN

Stack Overflow用户
提问于 2016-01-13 04:11:24
回答 2查看 80关注 0票数 1

我有以下代码:

代码语言:javascript
复制
{-# 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)

但是,我从编译器那里得到了以下错误,编译器的意思很难理解:

代码语言:javascript
复制
/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的容器,它应该考虑到可折叠性,但是这个错误信息对我来说没有任何意义。有人能澄清一下我在这里没能理解什么吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-01-13 04:32:12

你试过实际实现这个类吗?在默认定义和类型家族中,似乎有一些奇怪之处。如果您至少定义了以下内容,那么文件类型将检查:

代码语言:javascript
复制
instance MonoFoldable (RuleSet a) where --this is unhappy
    ofoldl1Ex' = undefined
    ofoldr1Ex  = undefined
    ofoldl'    = undefined
    ofoldr     = undefined
    ofoldMap   = undefined

编辑:高级序曲,我现在知道我永远不会使用它,它有默认的实现和类型签名,其中包括约束t a ~ mono, a ~ Element (t a)。工作很仔细,因为我不得不三思而后行。t a ~ RuleSet a0所以t == RuleSeta == a0。然后a ~ Element (RuleSet a),这是您在消息中的准确错误,将建议a ~ Rule a,这就是不对的。

票数 3
EN

Stack Overflow用户

发布于 2016-01-13 09:04:12

为了澄清默认的实现:由于有大量的类型是正确多态的--因此Functor - MonoFunctor的实例提供了一种简单的方法,可以通过默认方法签名来生成MonoFunctor的实例。在有Functor的情况下,只需声明instance MonoFunctor就足够了。

在您的示例中,您会得到一条令人困惑的错误消息,因为您的类型实际上是Functor,但类型与所需的MonoFunctor实例不同。具体来说,就其形状而言,RuleSet aaFunctor,而您希望它是Rule a。这没有什么问题,它只是与默认实现相冲突,因此您需要提供单独的实现。

请注意,这并不是特定于您的类型:任何不是简单的从FunctorMonoFunctor的转换都需要这项工作。这适用于一些内置实例,如TextByteString

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34758264

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档