
On Wednesday 25 August 2010 18:59:26, Oscar Finnsson wrote:
Thanks for the tip. You saved my day (and code)!
So what is the point of having the constraint on the left side of the '='?
I don't really know. What it does is preventing users from constructing values with arguments whose types don't satisfy the constraints. That probably seemed more useful before the experience than it really is. Says the report: http://www.haskell.org/onlinereport/haskell2010/haskellch4.html#x10-680004.2 "For example, the declaration data Eq a => Set a = NilSet | ConsSet a (Set a) introduces a type constructor Set of kind ∗→∗, and constructors NilSet and ConsSet with types NilSet :: ∀ a. Set a ConsSet :: ∀ a. Eq a ⇒ a → Set a → Set a In the example given, the overloaded type for ConsSet ensures that ConsSet can only be applied to values whose type is an instance of the class Eq. Pattern matching against ConsSet also gives rise to an Eq a constraint. For example: f (ConsSet a s) = a the function f has inferred type Eq a => Set a -> a. The context in the data declaration has no other effect whatsoever." ghci> case (NilSet :: Set (Int -> Bool)) of { NilSet -> True; _ -> False } True Note that the constraint doesn't apply to NilSet, because that constructor has no arguments (how the context on the data declaration is mapped to type class constraints on the constructors is explained in the report).
Will it allow me to do anything that the right-side constraint won't?
Nothing useful, as far as I know.