Skip to content

Ambiguous function accepted by compiler

Summary

GHCi accepts a function implemented without a signature. When the signature inferred by GHCi is declared for the function, GHCi refuses the code for ambiguity reasons.

Steps to reproduce

Step 1

Load this code into GHCi:

{-# LANGUAGE ConstraintKinds #-}  
{-# LANGUAGE DataKinds #-}  
{-# LANGUAGE DeriveFunctor #-}  
{-# LANGUAGE DuplicateRecordFields #-}  
{-# LANGUAGE FlexibleContexts #-}  
{-# LANGUAGE FlexibleInstances #-}  
{-# LANGUAGE GADTs #-}  
{-# LANGUAGE KindSignatures #-}  
{-# LANGUAGE MultiParamTypeClasses #-}  
{-# LANGUAGE PolyKinds #-}  
{-# LANGUAGE TypeFamilies #-}  
{-# LANGUAGE TypeOperators #-}  
{-# LANGUAGE TypeApplications #-}  
{-# LANGUAGE AllowAmbiguousTypes #-}  
{-# LANGUAGE ScopedTypeVariables #-}  

import Data.Kind (Constraint, Type)  
newtype MyInt   = MyInt   Int  

class Newtype a b where  
  wrap   :: a -> b  
  unwrap :: b -> a  

instance Newtype Int MyInt where  
  wrap = MyInt  
  unwrap (MyInt i) = i  

add x y = wrap $ unwrap x + unwrap y  

Step 2

Now type: :t add in GHCi
The answer will be: add :: (Num a, Newtype a b1, Newtype a b2, Newtype a b3) => b2 -> b3 -> b1

Step 3

Copy the type signature given by GHCi into the code like so:

add :: (Num a, Newtype a b1, Newtype a b2, Newtype a b3) => b2 -> b3 -> b1  
add x y = wrap $ unwrap x + unwrap y

Step 4

Try to reload the code with GHCi. The load will fail, and GHCi will complain about ambiguous types.

Expected behavior

GHCi should either refuse the code from the beginning for being ambiguous, or it should accept its own inferred signature as a valid signature.

Environment

  • GHC version used: 8.6.3

Optional:

  • Operating System: Linux 4.18.0-16-generic
  • System Architecture: x86_64
Edited by Simon Jakobi
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information