Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Strange type inferencе with RankNTypes extension

Tags:

haskell

ghc

I am trying to experiment with System-F types in Haskell and have implemented Church encoding of natural numbers via type.

When loading this code

{-# OPTIONS_GHC -Wall #-}
{-# LANGUAGE RankNTypes #-}

type CNat = forall t . (t -> t) -> (t -> t)

c0 :: CNat
c0 _ x = x

type CPair a b = forall t . (a -> b -> t) -> t

cpair :: a -> b -> CPair a b
cpair a b f = f a b

-- pair3 :: CPair CNat String
pair3 = cpair c0 "hello"

into ghci 7.8.2 I get a warning:

λ: :l test.hs 
[1 of 1] Compiling Main             ( test.hs, interpreted )

test.hs:29:1: Warning:
    Top-level binding with no type signature:
      pair3 :: forall t t1.
               (((t1 -> t1) -> t1 -> t1) -> [Char] -> t) -> t
Ok, modules loaded: Main.
λ: 

The question is, shouldn't the type be

pair3 :: forall t.
      ((forall t1. (t1 -> t1) -> t1 -> t1) -> [Char] -> t) -> t

?

UPD: A simpler example is provided

like image 897
amakarov Avatar asked May 08 '14 04:05

amakarov


2 Answers

That's a perfectly good type for it... but it's not the type Hindley-Milner gives it. HM always infers a rank-1 type. Inferring rank-2 types is actually decidable, I believe, but GHC doesn't even try.

like image 91
Daniel Wagner Avatar answered Nov 03 '22 21:11

Daniel Wagner


But is there any way to specify my type for it so that when I specify it explicitly (uncomment the line in my code), the compiler would not infer it but just check the provided type? Now I am getting error

If you want to instantiate the type variables a,b occurring in the type of cpair, you can add the following explicit annotation.

pair3 :: CPair CNat String
pair3 = (cpair :: CNat -> String -> CPair CNat String) c0 "hello"

Without that, cpair is only instantiated at monomorphic types, I believe.

like image 26
chi Avatar answered Nov 03 '22 19:11

chi