Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can I not use type variables in this instance declaration?

Tags:

haskell

I'm trying to use TypeApplications to disambiguate between which instance of a type class I am calling. Unfortunately, it seems that an instance declaration's type parameters cannot be used in the instance body. Specifically, in this toy example:

{-# LANGUAGE FlexibleInstances    #-}
{-# LANGUAGE TypeApplications     #-}
{-# LANGUAGE UndecidableInstances #-}

class Foo a where
    foo :: String

instance Foo () where
    foo = "()"

instance Foo Int where
    foo = "Int"

class Bar b where
    bar :: String

instance Foo a => Bar a where
    bar = foo @a

will error with Not in scope: type variable 'a' at the last line. If I remove the type application, instead the error Could not deduce (Foo a0) from the context Foo a is given, which is reasonable, ass foo by itself is ambiguous.

Is there some way for me to access the type parameter, or otherwise coerce the compiler into recognising this?

like image 523
Thomas Kerber Avatar asked Oct 19 '25 01:10

Thomas Kerber


1 Answers

A type variable can be used in an instance declaration, but only if it's scoped:

{-# LANGUAGE FlexibleInstances, UndecidableInstances #-}
{-# LANGUAGE TypeApplications, AllowAmbiguousTypes   #-}
{-# LANGUAGE ScopedTypeVariables, UnicodeSyntax      #-}

class Foo a where foo :: String

class Bar b where bar :: String

instance ∀ a . Foo a => Bar a where
  bar = foo @a

As always, can also be written forall if you prefer ASCII.

like image 99
leftaroundabout Avatar answered Oct 22 '25 05:10

leftaroundabout



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!