Reputation: 567
I have problem for realisation of next in Haskell:
Type class:
class CArgumentableAttr a where
expressArgumentAttr :: a -> (WidgetUI -> UI WidgetUI)
instance CArgumentableAttr (WidgetUI -> UI WidgetUI) where expressArgumentAttr a = a
and realisation:
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
here:
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 ++ "%")
It use for:
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:" ...
When compiling get the following error:
Malformed instance: CArgumentableAttr (CSizeable b) => ((b, b, b, b) -> UI_StartingPoint -> WidgetUI -> UI WidgetUI)
What can be done in this? Thank you!
Upvotes: 0
Views: 820
Reputation: 4540
I think @Toxaris identified the issue, but I wanted propose some potential adjustments that may make things easier for you.
A few red flags for me are:
CSizeable
instances for both Int
and String
- this of course isn't wrong in any way taken in isolationCSizeable Int
instance always assumes pixels which prevents you from ever being able to, for example, numerically represent a percentageCSizeable String
instanceCArgumentableAttr
instanceMy thought is that perhaps CSizeable
would be better as a plain data type instead of a class, or that you would have newtype wrappers instead of instances for Int
and String
.
As a data type:
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:" ...
The newtype wrappers could look something like this:
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
Upvotes: 4
Reputation: 7266
You use
instance CArgumentableAttr (CSizeable b) => ... where ...
but I think you want
instance (CSizeable b) => CArgumentableAttr ... where ...
instead.
Upvotes: 3