Haskell:格式错误的实例

Haskell:格式错误的实例,haskell,Haskell,我在Haskell实现next时遇到问题: 类型类别: class CArgumentableAttr a where expressArgumentAttr :: a -> (WidgetUI -> UI WidgetUI) instance CArgumentableAttr (WidgetUI -> UI WidgetUI) where expressArgumentAttr a = a 和实现: instance CArgumentableAttr

我在Haskell实现next时遇到问题:

类型类别:

class CArgumentableAttr a where
    expressArgumentAttr :: a -> (WidgetUI -> UI WidgetUI)

instance CArgumentableAttr (WidgetUI -> UI WidgetUI) where expressArgumentAttr a = a     
和实现:

instance CArgumentableAttr (CSizeable b) => ((b, b, b, b) -> UI_StartingPoint -> WidgetUI -> UI WidgetUI) where expressArgumentAttr a = a (0, 0, 100, 50) UI_LT 
instance CArgumentableAttr (UI_StartingPoint -> WidgetUI -> UI WidgetUI) where expressArgumentAttr a = aUI_LT 
在这里:

它用于:

bounds :: CSizeable a => (a, a, a, a) -> UI_StartingPoint -> WidgetUI -> UI WidgetUI
bounds (x, y, width, height) startingPoint widget =
    case startingPoint of 
        UI_LT -> applyStyleToWidget widget ("left:"  ++ (showSize x) ++ ";top:" ...
编译时出现以下错误:
格式错误的实例:CArgumentableAttr(CSizeable b)=>((b,b,b)->UI\u StartingPoint->WidgetUI->UI-WidgetUI)

在这方面可以做些什么? 谢谢大家!

您使用

instance CArgumentableAttr (CSizeable b) => ... where ...
但我想你想要

instance (CSizeable b) => CArgumentableAttr ... where ...

相反。

我认为@Toxaris发现了这个问题,但我想提出一些可能的调整,让事情变得更容易

对我来说,有几个危险信号是:

  • 对于
    Int
    String
    ,都有
    CSizeable
    实例-这当然不是孤立的错误
  • 例如,
    CSizeable Int
    实例始终假定像素无法以数字表示百分比
  • CSizeable字符串
    实例中存在“解析/检查”
  • CArgumentableAttr
    实例中有“无单位”编号
  • 我的想法是,
    CSizeable
    作为普通数据类型而不是类可能会更好,或者您可以使用新类型包装器而不是
    Int
    String
    的实例

    作为数据类型:

    data Size = Pixels Int | Percent Double | Literal String
    instance Show Size where
      show (Pixels x) = show x ++ "px"
      show (Percent x) = show x ++ "%"
      show (Literal x) = x
    
    instance CArgumentableAttr ((Size,Size,Size,Size) -> UI_StartingPoint -> WidgetUI -> UI WidgetUI) where expressArgumentAttr a = a (Pixels 0, Pixels 0, Pixels 100, Pixels 50) UI_LT
    instance CArgumentableAttr (UI_StartingPoint -> WidgetUI -> UI WidgetUI) where expressArgumentAttr a = a UI_LT
    
    bounds :: (Size,Size,Size,Size) -> UI_StartingPoint -> WidgetUI -> UI WidgetUI
    bounds (x,y,width,height) startingPoint widget =
      case startingPoint of
        UI_LT -> applyStyleToWidget widget ("left:"  ++ show x ++ ";top:" ...
    
    新类型的包装可以如下所示:

    newtype Pixels = Pixels Int
    newtype Percent = Percent Double
    newtype Literal = Literal String
    
    instance CSizeable Pixels where showSize (Pixels x) = show x ++ "px"
    instance CSizeable Percent where showSize (Percent x) = show x ++ "%"
    instance CSizeable Literal where showSize (Literal x) = x
    

    错误消息通常包含需要激活的扩展名。但是,对
    b
    的约束应该放在第一位,例如
    实例CSizeable b=>CArgumentableAttr
    。这通常需要
    -XFlexibleInstances
    我使用
    FlexibleInstances
    如果使用
    XFlexibleInstances
    那么
    …b9416b003--启用测试--启用基准进程,退出代码:ExitFailure 1
    setup-Simple-Cabal-1.22.5.0-ghc-7.10.3:包Lizard-0.1.0.0需要以下语言ghc-7.10.3不支持的扩展:XFlexibleInstances不会在注释中添加其他信息,而是在您的问题中添加。在这种情况下,
    code
    无法从上下文(CSizeable b)推断文字“0”产生的(Num b)受src/WebUI/Widgets/UIWidget.hs:642:10-105处的实例声明约束可能的修复:将(Num b)添加到表达式中实例声明的上下文中:a的第一个参数中的0,即表达式中的(0,0,100,50):a(0,0,100,50)用户界面_LT@QSpider您需要添加一个
    numb
    约束:
    实例(numb,CSizeable b)=>CArgumentableAttr
    Num
    typeclass的实现提供了将整数文本解释为给定类型的逻辑。这可能会有问题,因为您有一个
    String
    实例,所以您可能希望扩展
    CSizeable
    typeclass以支持文本实例化,而不是实现
    Num String
    newtype Pixels = Pixels Int
    newtype Percent = Percent Double
    newtype Literal = Literal String
    
    instance CSizeable Pixels where showSize (Pixels x) = show x ++ "px"
    instance CSizeable Percent where showSize (Percent x) = show x ++ "%"
    instance CSizeable Literal where showSize (Literal x) = x