higher-rank-types

RankNTypes with type aliases confusion [duplicate]

帅比萌擦擦* 提交于 2019-12-05 23:07:01
This question already has an answer here: Understanding a rank 2 type alias with a class constraint 2 answers I'm trying to understand how type constraints work with type aliases. First, let's assume I have next type alias: type NumList a = Num a => [a] And I have next function: addFirst :: a -> NumList a -> NumList addFirst x (y:_) = x + y This function fails with next error: Type.hs:9:13: error: • No instance for (Num a) arising from a pattern Possible fix: add (Num a) to the context of the type signature for: addFirst :: a -> NumList a -> a • In the pattern: y : _ In an equation for

List of existentially quantified values in Haskell

白昼怎懂夜的黑 提交于 2019-12-05 16:20:21
I'm wondering why this piece of code doesn't type-check: {-# LANGUAGE ScopedTypeVariables, Rank2Types, RankNTypes #-} {-# OPTIONS -fglasgow-exts #-} module Main where foo :: [forall a. a] foo = [1] ghc complains: Could not deduce (Num a) from the context () arising from the literal `1' at exist5.hs:7:7 Given that: Prelude> :t 1 1 :: (Num t) => t Prelude> it seems that the (Num t) context can't match the () context of arg. The point I can't understand is that since () is more general than (Num t), the latter should and inclusion of the former. Has this anything to do with lack of Haskell

How can eta-reduction of a well typed function result in a type error?

南楼画角 提交于 2019-12-05 11:16:34
问题 I was playing around with van Laarhoven lenses and ran into a problem where the type-checker rejects the eta-reduced form of a well-typed function: {-# LANGUAGE RankNTypes #-} import Control.Applicative type Lens c a = forall f . Functor f => (a -> f a) -> (c -> f c) getWith :: (a -> b) -> ((a -> Const b a) -> (c -> Const b c)) -> (c -> b) getWith f l = getConst . l (Const . f) get :: Lens c a -> c -> a get lens = getWith id lens The above type-checks but if I eta-reduce get to get :: Lens c

Referential transparency with polymorphism in Haskell

与世无争的帅哥 提交于 2019-12-04 22:48:13
Say I have a function: f :: Int -> (Rational, Integer) f b = ((toRational b)+1,(toInteger b)+1) I want to abstract away the (+1) like so: f :: Int -> (Rational, Integer) f b = (h (toRational b) ,h (toInteger b)) where h = (+1) This wont work obviously, but if I specify the type signature it will work: f :: Int -> (Rational, Integer) f b = (h (toRational b) ,h (toInteger b)) where h :: Num a => a -> a h = (+1) Say I now want to further abstract the function by passing h as a parameter: f :: Num a => Int -> (a -> a) -> (Rational, Integer) f b g = (h (toRational b) ,h (toInteger b)) where h ::

Are there any advantages of using Rank2Types in favor of RankNTypes?

≯℡__Kan透↙ 提交于 2019-12-04 22:16:52
As far as I know, a decidable type checking algorithm exists (only) for rank-2 types. Does GHC use somehow this fact, and does it have any practical implications? Is there also a notion of principal types for rank-2 types, and a type inference algorithm? If yes, does GHC use it? Are there any other advantages of rank-2 types over rank- n types? Rank2Types is a synonym for RankNTypes . So right now there are no advantages of rank-2 over rank-n. In principle type checking is decidable for rank 2 types. But, that was never going to be included in GHC (overly complicated, doesn't mix well with

How can eta-reduction of a well typed function result in a type error?

荒凉一梦 提交于 2019-12-03 23:11:57
I was playing around with van Laarhoven lenses and ran into a problem where the type-checker rejects the eta-reduced form of a well-typed function: {-# LANGUAGE RankNTypes #-} import Control.Applicative type Lens c a = forall f . Functor f => (a -> f a) -> (c -> f c) getWith :: (a -> b) -> ((a -> Const b a) -> (c -> Const b c)) -> (c -> b) getWith f l = getConst . l (Const . f) get :: Lens c a -> c -> a get lens = getWith id lens The above type-checks but if I eta-reduce get to get :: Lens c a -> c -> a get = getWith id Then GHC (7.4.2) complains that Couldn't match expected type `Lens c a'

Juggling existentials without unsafeCoerce

微笑、不失礼 提交于 2019-12-03 12:44:07
Lately I have been playing with this type, which I understand to be an encoding of the free distributive functor (for tangential background on that, see this answer ): data Ev g a where Ev :: ((g x -> x) -> a) -> Ev g a deriving instance Functor (Ev g) The existential constructor ensures I can only consume an Ev g by supplying a polymorphic extractor forall x. g x -> x , and that the lift and lower functions of the free construction can be given compatible types: runEv :: Ev g a -> (forall x. g x -> x) -> a runEv (Ev s) f = s f evert :: g a -> Ev g a evert u = Ev $ \f -> f u revert ::

Why are higher rank types so fragile in Haskell

徘徊边缘 提交于 2019-12-03 12:27:09
I was messing around with the runST function. Which has type (forall s. ST s a) -> a and it seems like trying to use it in any way that isn't directly applying without any indirection breaks it in pretty nasty ways. runST :: (forall s. ST s a) -> a const :: a -> b -> a so by substituting a in const for forall s. ST s a you should get the type of const runST const runST :: b -> (forall s. ST s a) -> a but instead GHC says that it can't match a with (forall s. ST s a) -> a but since a literally means forall a. a which is satisfied by every type I don't see what is invalid about that. As it turns

RankNTypes and scope of `forall'

扶醉桌前 提交于 2019-12-03 11:05:31
What is the difference between these? {-# LANGUAGE RankNTypes #-} f :: forall a. a -> Int f _ = 1 g :: (forall a. a) -> Int g _ = 1 In particular, why do I get an error with g () ? ghci> f () 1 ghci> g () <interactive>:133:3: Couldn't match expected type `a' with actual type `()' `a' is a rigid type variable bound by a type expected by the context: a at <interactive>:133:1 In the first argument of `g', namely `()' In the expression: g () In an equation for `it': it = g () ghci> f undefined 1 ghci> g undefined 1 f is just an ordinary polymorphic Haskell98 function, except the forall is written

How should the general type of a “lemma” function be understood?

半腔热情 提交于 2019-12-03 05:54:20
Perhaps this is a stupid question. Here's a quote from the Hasochism paper : One approach to resolving this issue is to encode lemmas, given by parameterised equations, as Haskell functions. In general, such lemmas may be encoded as functions of type: ∀ x1 ... xn. Natty x1 → ... → Natty xn → ((l ~ r) ⇒ t) → t I thought I understood RankNTypes , but I can't make sense of the last part of this proposition. I'm reading it informally as "given a term which requires l ~ r , return that term". I'm sure this interpretation is wrong because it seems to lead to a circularity: we don't know l ~ r until