Skip to content

SuperComposition instance resolution is brittle #265

Description

@treeowl

In GHCi:

ghci> :t ("b"++)
("b"++) :: [Char] -> [Char]
ghci> :t ('b':)
('b':) :: [Char] -> [Char]

ghci> :t (++"a") ... ("b"++)
(++"a") ... ("b"++) :: [Char] -> [Char]
ghci> :t (++"a") ... ('b': )

<interactive>:1:9: error:
    • Couldn't match type: [Char]
                     with: [Char] -> [Char]
        arising from a use of ‘...’
    • In the expression: (++ "a") ... ('b' :)

Ouch! I'd be tempted to go with something simpler:

infixl 8 ...

class SuperComposition x y b r | x y b -> r where
  (...) :: (x -> y) -> b -> r

instance {-# OVERLAPPABLE #-} (x ~ b, y ~ r) => SuperComposition x y b r where
  f ... g = f g
  {-# INLINE (...) #-}

instance {-# OVERLAPPING #-} (SuperComposition x y d r1, r ~ (c -> r1)) => SuperComposition x y (c -> d) r where
  (f ... g) c = f ... g c
  {-# INLINE (...) #-}

I used four parameters instead of three to be able to infer directly that the first argument of (...) is a function. We could do that with three parameters too, but it gets a little hacky and I don't see a real advantage.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions