Haskell:格式错误的实例

时间:2016-09-12 11:27:01

标签: haskell

我在Haskell中实现下一个问题:

键入类:

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 

这里:

class Show a => CSizeable a where
    showSize :: a -> String
instance CSizeable Int where
    showSize a = (show a) ++ "px"
instance CSizeable String where
    showSize a = if '%' `elem` a then a else (a ++ "%")

用于:

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,b) - > UI_StartingPoint - > WidgetUI - > UI WidgetUI)

这可以做些什么? 谢谢!

2 个答案:

答案 0 :(得分:4)

我认为@Toxaris确定了这个问题,但我想提出一些可能会让您更轻松的潜在调整。

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

  1. CSizeableInt都有String个实例 - 这当然不是错误以任何方式孤立地进行
  2. CSizeable Int实例总是假设像素会阻止您(例如,数字表示百分比)
  3. 解析/检查"在CSizeable String实例
  4. 有"无单位" CArgumentableAttr实例中的数字
  5. 我的想法是,或许CSizeable作为普通数据类型而不是类更好,或者您将拥有newtype包装而不是IntString的实例。< / p>

    作为数据类型:

    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包装器看起来像这样:

    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
    

答案 1 :(得分:3)

您使用

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

但我认为你想要

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

代替。