Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
228 views
in Technique[技术] by (71.8m points)

Defaulting typeclass instances in Haskell and PureScript

I have a simple class that has an instance for Int and []/Array in Haskell/PureScript:

HS:

class C c where f :: c -> c
instance C Int where f x = x
instance C c => C [c] where f l = map f l

PS:

class C c where f :: c -> c
instance intC :: C Int where f x = x
instance arrC :: C c => C (Array c) where f l = map f l

In both representations the value of f [] is [] –?regardless of the instantiation of the type c. However, when I write

f []

I get an ambiguity error:

HS:

    ? Ambiguous type variable ‘a0’ arising from a use of ‘f’
      prevents the constraint ‘(C a0)’ from being solved.

PS:

  The inferred type
    forall t4. C t4 => Boolean
  has type variables which are not determined by those mentioned in the body of the type:
    t4 could not be determined

Understandable; there is indeed an ambiguity which confuses the compiler during the class dictionary assignment. However, in this particular case it should not be a problem, as the only case where c is undetermined is when the list is empty, so when the result is known.

Is it possible to convince the compiler to default the unset typevars to something specific? I would like to automatically solve ambiguities with that class by instantiating them with Int, for example. I know that it already happens with the Num class: I even sometimes get a warning that "2137 was defaulted to be an Integer" in Haskell. Asking about both languages, I am aware that the answers might be slightly different.

question from:https://stackoverflow.com/questions/65952118/defaulting-typeclass-instances-in-haskell-and-purescript

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Here's a sort of option.

data CList a where
  CNil :: CList a
  CCons :: C a => a -> CList a -> CList a

instance C (CList a) where
  f CNil = CNil
  f (CCons x xs) = CCons (f x) (f xs)

For a plain list, the best I can think of is to enable ExtendedDefaultRules and define

instance C () where
  f ~() = ()

I believe this should default your [] to [] :: [()] and do the right thing.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...