我在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)
这可以做些什么? 谢谢!
答案 0 :(得分:4)
我认为@Toxaris确定了这个问题,但我想提出一些可能会让您更轻松的潜在调整。
对我来说有几个危险信号:
CSizeable
和Int
都有String
个实例 - 这当然不是错误以任何方式孤立地进行CSizeable Int
实例总是假设像素会阻止您(例如,数字表示百分比)CSizeable String
实例CArgumentableAttr
实例中的数字我的想法是,或许CSizeable
作为普通数据类型而不是类更好,或者您将拥有newtype包装而不是Int
和String
的实例。< / 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 ...
代替。