Type error when messing up with lenses [duplicate] - haskell

This question already has answers here:
Why do 3 and x (which was assigned 3) have different inferred types in Haskell? [duplicate]
(3 answers)
Closed 7 years ago.
I am encountering a type error when trying to compile some lens code.
{-# LANGUAGE TemplateHaskell #-}
import Control.Lens.Setter (over)
import Control.Lens.Getter (view)
import Control.Lens.TH
data IL = IL {
_ilL :: [Int]
}
deriving (Show)
makeLenses ''IL
val = IL [1, 2, 3]
(val1, val2) = let l = ilL
in (over l tail val, view l val)
The error is:
Test.hs:17:35:
Couldn't match expected type `Control.Lens.Internal.Getter.Accessor [Int] [Int]'
with actual type `Control.Lens.Internal.Setter.Mutator [Int]'
Expected type: Control.Lens.Getter.Getting [Int] s0 [Int]
Actual type: ([Int]
-> Control.Lens.Internal.Setter.Mutator [Int])
-> IL -> Control.Lens.Internal.Setter.Mutator IL
In the first argument of `view', namely `l'
In the expression: view l val
This error goes away if I use ilL directly. However, I really need to make a lens definition using let. How can I solve this?

Yet another case of the dreaded monomorphism restriction. Add {-# LANGUAGE NoMonormorphismRestriction #-} at the top of your file and it will compile just fine.
The reason is because when you do let l = ilL in ... without an explicit type signature (or the MR disabled) GHC wants to specialize the type of l as much as it can. It first encounters its use in over l tail val and specializes to the type needed there, but this conflicts with the specialized inferred type in view l val. The solution is to disable the MR or add explicit type signatures like
(val1, val2) =
let l :: Lens' IL [Int]
l = ilL
in (over l tail val, view l val)
This is very similar to a more simple case like
x = let y = 1
z = 2 :: Int
w = 3 :: Double
in (z + y, w + y)
What should the type of y be? With the MR the compiler wants to restrict the type of y to be a single type, but we would really like it to have the type Num a => a since this can work with Ints or Doubles. With the MR turned off the compiler won't specialize the type of y and everything works as expected. The alternative is to give y an explicit type signature, but why do all that work when we can make the compiler do it for us?

Related

Type-level constraints in Haskell

I'm trying to encode term algebra as a data type in Haskell for further use in an algorithm. By term algebra I mean a set of terms which are either variables or functions applied to other terms. The functions with zero arguments are constants (but that's actually does not matter here).
Firstly, one would need the following GHC language extensions to replicate my code:
{-# LANGUAGE GADTs, DataKinds,
TypeApplications,
TypeFamilies,
TypeOperators,
StandaloneKindSignatures,
UndecidableInstances#-}
and the following imports:
import qualified GHC.TypeLits as GTL
import Data.Kind
The direct way to encode terms (the first one I took):
data Term where
Var :: String -> Term
Func :: String -> Integer -> [Term] -> Term
where by String I want to encode the name, by Integer the arity and by [Terms] the list of arguments of a function.
Then I want to be sure that the list of terms as arguments have the same length as an arity.
The first idea is to use smart constructors, but I would like to encode such constraints on a type level. So the second idea would be to create type-level naturals, lists of a specified length and the data type where these numbers coincide:
data Z = Z
data S a = S a
data List n a where
Nil :: List Z a
Cons :: a -> List m a -> List (S m) a
data WWTerm where
WWVar :: String -> WWTerm
WWFunc :: String -> m -> List m WWTerm -> WWTerm
My question here is the following: is there a way to impose type-level constraints using ordinary lists at the same time via 1) creating special type-families, 2) creating special type classes, or 3) via constraints in data types?
Regarding my attempts, I wrote the following:
type MyLength :: [Type] -> GTL.Nat
type family MyLength xs where
MyLength '[] = 0
MyLength (x':xs) = 1 GTL.+ (MyLength xs)
data QFunc n l where
QFunc :: (MyLength l ~ n) => String -> (n :: GTL.Nat) -> l -> QFunc n l
Unfortunately, this part of code doesn't compile for the following reasons:
Expected a type, but ‘n :: Nat’ has kind ‘Nat’
...
Expected a type, but ‘l’ has kind ‘[*]’
...
Are there any thoughts on how to approach my goal?

Weird Error When Defining a Type Synonym of a Type Synonym (GHC)

Background
I have written the following code in Haskell (GHC):
{-# LANGUAGE
NoImplicitPrelude,
TypeInType, PolyKinds, DataKinds,
ScopedTypeVariables,
TypeFamilies
#-}
import Data.Kind(Type)
data PolyType k (t :: k)
type Wrap (t :: k) = PolyType k t
type Unwrap pt = (GetType pt :: GetKind pt)
type family GetType (pt :: Type) :: k where
GetType (PolyType k t) = t
type family GetKind (pt :: Type) :: Type where
GetKind (PolyType k t) = k
The intention of this code is to allow me to wrap a type of an arbitrary kind into a type (namely PolyType) of a single kind (namely Type) and then reverse the process (i.e. unwrap it) later.
Problem
I would like to define a type synonym for Unwrap akin to the following:
type UnwrapSynonym pt = Unwrap pt
However, the above definition produces the following error (GHC 8.4.3):
* Invalid declaration for `UnwrapSynonym'; you must explicitly
declare which variables are dependent on which others.
Inferred variable kinds: pt :: *
* In the type synonym declaration for `UnwrapSynonym'
What does this error mean? Is there a way I can get around it in order to define UnwrapSynonym?
What I Have Been Doing
My approach to this problem thus far is to essentially manually inline Uwrap in any high-order type synonyms I wish to define, but that feels icky, and I am hoping there is a better way.
Unfortunately, I am not experienced enough with the inner workings of GHC even understand exactly what the problem is much less figure out how to fix it.
I believe I have a decent understanding of how the extensions I'm using (ex. TypeInType and PolyKinds) work, but it is apparently not deep enough to understand this error. Furthermore, I have not been able to find an resources that address a similar problem. This is partly because I don't know how to succinctly describe it, which also made it hard to come up with a good title for this question.
The error is quite obtuse, but what I think it's trying to say is that GHC has noticed that the kind of UnwrapSynonym is dependent, forall (pt :: Type) -> GetKind pt, and it wants you to explicitly annotate the dependency:
type UnwrapSynonym pt = (Unwrap pt :: GetKind pt)
The reason it's talking about telling it "which variables are dependent on which others" is because this error can also pop up in e.g. this situation:
data Nat = Z | S Nat
data Fin :: Nat -> Type where
FZ :: Fin (S n)
FS :: Fin n -> Fin (S n)
type family ToNat (n :: Nat) (x :: Fin n) :: Nat where
ToNat (S n) FZ = Z
ToNat (S n) (FS x) = S (ToNat n x)
type ToNatAgain n x = ToNat n x -- similar error
ToNatAgain should have kind forall (n :: Nat) -> Fin n -> Nat, but the type of the variable x depends on the type of the variable n. GHC wants that explicitly annotated, so it tells me to tell it which variables depend on which other variables, and it gives me what it inferred as their kinds to help do that.
type ToNatAgain (n :: Nat) (x :: Fin n) = ToNat n x
In your case, the dependency is between the return kind and the argument kind. The underlying reason is the same, but the error message was apparently not designed with your case in mind and doesn't fit. You should submit a bug report.
As an aside, do you really need separate Unwrap and GetType? Why not make GetType dependent?
type family GetType (pt :: Type) :: GetKind pt where
GetType (PolyType k t) = t

What can type families do that multi param type classes and functional dependencies cannot

I have played around with TypeFamilies, FunctionalDependencies, and MultiParamTypeClasses. And it seems to me as though TypeFamilies doesn't add any concrete functionality over the other two. (But not vice versa). But I know type families are pretty well liked so I feel like I am missing something:
"open" relation between types, such as a conversion function, which does not seem possible with TypeFamilies. Done with MultiParamTypeClasses:
class Convert a b where
convert :: a -> b
instance Convert Foo Bar where
convert = foo2Bar
instance Convert Foo Baz where
convert = foo2Baz
instance Convert Bar Baz where
convert = bar2Baz
Surjective relation between types, such as a sort of type safe pseudo-duck typing mechanism, that would normally be done with a standard type family. Done with MultiParamTypeClasses and FunctionalDependencies:
class HasLength a b | a -> b where
getLength :: a -> b
instance HasLength [a] Int where
getLength = length
instance HasLength (Set a) Int where
getLength = S.size
instance HasLength Event DateDiff where
getLength = dateDiff (start event) (end event)
Bijective relation between types, such as for an unboxed container, which could be done through TypeFamilies with a data family, although then you have to declare a new data type for every contained type, such as with a newtype. Either that or with an injective type family, which I think is not available prior to GHC 8. Done with MultiParamTypeClasses and FunctionalDependencies:
class Unboxed a b | a -> b, b -> a where
toList :: a -> [b]
fromList :: [b] -> a
instance Unboxed FooVector Foo where
toList = fooVector2List
fromList = list2FooVector
instance Unboxed BarVector Bar where
toList = barVector2List
fromList = list2BarVector
And lastly a surjective relations between two types and a third type, such as python2 or java style division function, which can be done with TypeFamilies by also using MultiParamTypeClasses. Done with MultiParamTypeClasses and FunctionalDependencies:
class Divide a b c | a b -> c where
divide :: a -> b -> c
instance Divide Int Int Int where
divide = div
instance Divide Int Double Double where
divide = (/) . fromIntegral
instance Divide Double Int Double where
divide = (. fromIntegral) . (/)
instance Divide Double Double Double where
divide = (/)
One other thing I should also add is that it seems like FunctionalDependencies and MultiParamTypeClasses are also quite a bit more concise (for the examples above anyway) as you only have to write the type once, and you don't have to come up with a dummy type name which you then have to type for every instance like you do with TypeFamilies:
instance FooBar LongTypeName LongerTypeName where
FooBarResult LongTypeName LongerTypeName = LongestTypeName
fooBar = someFunction
vs:
instance FooBar LongTypeName LongerTypeName LongestTypeName where
fooBar = someFunction
So unless I am convinced otherwise it really seems like I should just not bother with TypeFamilies and use solely FunctionalDependencies and MultiParamTypeClasses. Because as far as I can tell it will make my code more concise, more consistent (one less extension to care about), and will also give me more flexibility such as with open type relationships or bijective relations (potentially the latter is solver by GHC 8).
Here's an example of where TypeFamilies really shines compared to MultiParamClasses with FunctionalDependencies. In fact, I challenge you to come up with an equivalent MultiParamClasses solution, even one that uses FlexibleInstances, OverlappingInstance, etc.
Consider the problem of type level substitution (I ran across a specific variant of this in Quipper in QData.hs). Essentially what you want to do is recursively substitute one type for another. For example, I want to be able to
substitute Int for Bool in Either [Int] String and get Either [Bool] String,
substitute [Int] for Bool in Either [Int] String and get Either Bool String,
substitute [Int] for [Bool] in Either [Int] String and get Either [Bool] String.
All in all, I want the usual notion of type level substitution. With a closed type family, I can do this for any types (albeit I need an extra line for each higher-kinded type constructor - I stopped at * -> * -> * -> * -> *).
{-# LANGUAGE TypeFamilies #-}
-- Subsitute type `x` for type `y` in type `a`
type family Substitute x y a where
Substitute x y x = y
Substitute x y (k a b c d) = k (Substitute x y a) (Substitute x y b) (Substitute x y c) (Substitute x y d)
Substitute x y (k a b c) = k (Substitute x y a) (Substitute x y b) (Substitute x y c)
Substitute x y (k a b) = k (Substitute x y a) (Substitute x y b)
Substitute x y (k a) = k (Substitute x y a)
Substitute x y a = a
And trying at ghci I get the desired output:
> :t undefined :: Substitute Int Bool (Either [Int] String)
undefined :: Either [Bool] [Char]
> :t undefined :: Substitute [Int] Bool (Either [Int] String)
undefined :: Either Bool [Char]
> :t undefined :: Substitute [Int] [Bool] (Either [Int] String)
undefined :: Either [Bool] [Char]
With that said, maybe you should be asking yourself why am I using MultiParamClasses and not TypeFamilies. Of the examples you gave above, all except Convert translate to type families (albeit you will need an extra line per instance for the type declaration).
Then again, for Convert, I am not convinced it is a good idea to define such a thing. The natural extension to Convert would be instances such as
instance (Convert a b, Convert b c) => Convert a c where
convert = convert . convert
instance Convert a a where
convert = id
which are as unresolvable for GHC as they are elegant to write...
To be clear, I am not saying there are no uses of MultiParamClasses, just that when possible you should be using TypeFamilies - they let you think about type-level functions instead of just relations.
This old HaskellWiki page does an OK job of comparing the two.
EDIT
Some more contrasting and history I stumbled upon from augustss blog
Type families grew out of the need to have type classes with
associated types. The latter is not strictly necessary since it can be
emulated with multi-parameter type classes, but it gives a much nicer
notation in many cases. The same is true for type families; they can
also be emulated by multi-parameter type classes. But MPTC gives a
very logic programming style of doing type computation; whereas type
families (which are just type functions that can pattern match on the
arguments) is like functional programming.
Using closed type families
adds some extra strength that cannot be achieved by type classes. To
get the same power from type classes we would need to add closed type
classes. Which would be quite useful; this is what instance chains
gives you.
Functional dependencies only affect the process of constraint solving, while type families introduced the notion of non-syntactic type equality, represented in GHC's intermediate form by coercions. This means type families interact better with GADTs. See this question for the canonical example of how functional dependencies fail here.

What does '#' mean in Haskell?

I've tried googling but come up short. I am furthering my Haskell knowledge by reading some articles and I came across one that uses a syntax I've never seen before.
An example would be:
reconstruct node#(Node a b c l r) parent#(Node b d le ri)
I've never seen these #'s before. I tried searching online for an answer but came up short. Is this simply a way to embed tags to help make things clearer, or do they have an actual impact on the code?
It is used in pattern matching. Now node variable will refer to the entire Node data type for the argument Node a b c l r. So instead of passing to the function as Node a b c l r, you can use node instead to pass it up.
A much simpler example to demonstrate it:
data SomeType = Leaf Int Int Int | Nil deriving Show
someFunction :: SomeType -> SomeType
someFunction leaf#(Leaf _ _ _) = leaf
someFunction Nil = Leaf 0 0 0
The someFunction can also be written as:
someFunction :: SomeType -> SomeType
someFunction (Leaf x y z) = Leaf x y z
someFunction Nil = Leaf 0 0 0
See how simpler was the first version ?
Using #t as a type indicator
Besides the argument pattern matching usage described in the answer of #Sibi, in Haskell the "at" character ('#', also known as an arobase character) can be used in some contexts to force a typing decision. This is mentioned in the comments by #Josh.F.
This is not part of the default language features, and is known as the Type Application Haskell language extension. In summary, the extension allows you to give explicit type arguments to a polymorphic function such as read. In a classic .hs source file, the relevant pragma must be included:
{-# LANGUAGE TypeApplications #-}
Example:
$ ghci
GHCi, version 8.2.2: http://www.haskell.org/ghc/ :? for help
λ>
λ> let x = (read #Integer "33")
<interactive>:4:10: error:
Pattern syntax in expression context: read#Integer
Did you mean to enable TypeApplications?
λ>
λ> :set -XTypeApplications
λ>
λ> let x = (read #Integer "33")
λ>
λ> :type x
x :: Integer
λ>
λ> x
33
λ>
Further details
For the read polymorphic function, the type indicator introduced by # relates to the type of the result returned by read. But this is not generally true.
Generally speaking, you have to consider the type variables that appear in the type signature of the function at hand. For example, let's have a look at the fmap library function.
fmap :: Functor ft => (a -> b) -> ft a -> ft b
So here, we have 3 type variables, in order of appearance: ft, a, b. If we specialize fmap like this:
myFmap = fmap #type1 #type2 #type3
then type1 will relate to ft, type2 will relate to a and type3 will relate to b. Also, there is a special dummy type indicator #_ which means: “here, any type goes”.
For example, we can force the output type of fmap to be Integer and the functor to be the plain list [], leaving the input type a unspecified:
λ>
λ> myFmap = fmap #[] #_ #Integer
λ>
λ> :type myFmap
myFmap :: (_ -> Integer) -> [_] -> [Integer]
λ>
As for the read function, its type is:
read :: Read a => String -> a
So there is only room for one type indicator, and it relates to the type of the result returned by read, as displayed above.

Haskell get type of algebraic parameter

I have a type
class IntegerAsType a where
value :: a -> Integer
data T5
instance IntegerAsType T5 where value _ = 5
newtype (IntegerAsType q) => Zq q = Zq Integer deriving (Eq)
newtype (Num a, IntegerAsType n) => PolyRing a n = PolyRing [a]
I'm trying to make a nice "show" for the PolyRing type. In particular, I want the "show" to print out the type 'a'. Is there a function that returns the type of an algebraic parameter (a 'show' for types)?
The other way I'm trying to do it is using pattern matching, but I'm running into problems with built-in types and the algebraic type.
I want a different result for each of Integer, Int and Zq q.
(toy example:)
test :: (Num a, IntegerAsType q) => a -> a
(Int x) = x+1
(Integer x) = x+2
(Zq x) = x+3
There are at least two different problems here.
1) Int and Integer are not data constructors for the 'Int' and 'Integer' types. Are there data constructors for these types/how do I pattern match with them?
2) Although not shown in my code, Zq IS an instance of Num. The problem I'm getting is:
Ambiguous constraint `IntegerAsType q'
At least one of the forall'd type variables mentioned by the constraint
must be reachable from the type after the '=>'
In the type signature for `test':
test :: (Num a, IntegerAsType q) => a -> a
I kind of see why it is complaining, but I don't know how to get around that.
Thanks
EDIT:
A better example of what I'm trying to do with the test function:
test :: (Num a) => a -> a
test (Integer x) = x+2
test (Int x) = x+1
test (Zq x) = x
Even if we ignore the fact that I can't construct Integers and Ints this way (still want to know how!) this 'test' doesn't compile because:
Could not deduce (a ~ Zq t0) from the context (Num a)
My next try at this function was with the type signature:
test :: (Num a, IntegerAsType q) => a -> a
which leads to the new error
Ambiguous constraint `IntegerAsType q'
At least one of the forall'd type variables mentioned by the constraint
must be reachable from the type after the '=>'
I hope that makes my question a little clearer....
I'm not sure what you're driving at with that test function, but you can do something like this if you like:
{-# LANGUAGE ScopedTypeVariables #-}
class NamedType a where
name :: a -> String
instance NamedType Int where
name _ = "Int"
instance NamedType Integer where
name _ = "Integer"
instance NamedType q => NamedType (Zq q) where
name _ = "Zq (" ++ name (undefined :: q) ++ ")"
I would not be doing my Stack Overflow duty if I did not follow up this answer with a warning: what you are asking for is very, very strange. You are probably doing something in a very unidiomatic way, and will be fighting the language the whole way. I strongly recommend that your next question be a much broader design question, so that we can help guide you to a more idiomatic solution.
Edit
There is another half to your question, namely, how to write a test function that "pattern matches" on the input to check whether it's an Int, an Integer, a Zq type, etc. You provide this suggestive code snippet:
test :: (Num a) => a -> a
test (Integer x) = x+2
test (Int x) = x+1
test (Zq x) = x
There are a couple of things to clear up here.
Haskell has three levels of objects: the value level, the type level, and the kind level. Some examples of things at the value level include "Hello, world!", 42, the function \a -> a, or fix (\xs -> 0:1:zipWith (+) xs (tail xs)). Some examples of things at the type level include Bool, Int, Maybe, Maybe Int, and Monad m => m (). Some examples of things at the kind level include * and (* -> *) -> *.
The levels are in order; value level objects are classified by type level objects, and type level objects are classified by kind level objects. We write the classification relationship using ::, so for example, 32 :: Int or "Hello, world!" :: [Char]. (The kind level isn't too interesting for this discussion, but * classifies types, and arrow kinds classify type constructors. For example, Int :: * and [Int] :: *, but [] :: * -> *.)
Now, one of the most basic properties of Haskell is that each level is completely isolated. You will never see a string like "Hello, world!" in a type; similarly, value-level objects don't pass around or operate on types. Moreover, there are separate namespaces for values and types. Take the example of Maybe:
data Maybe a = Nothing | Just a
This declaration creates a new name Maybe :: * -> * at the type level, and two new names Nothing :: Maybe a and Just :: a -> Maybe a at the value level. One common pattern is to use the same name for a type constructor and for its value constructor, if there's only one; for example, you might see
newtype Wrapped a = Wrapped a
which declares a new name Wrapped :: * -> * at the type level, and simultaneously declares a distinct name Wrapped :: a -> Wrapped a at the value level. Some particularly common (and confusing examples) include (), which is both a value-level object (of type ()) and a type-level object (of kind *), and [], which is both a value-level object (of type [a]) and a type-level object (of kind * -> *). Note that the fact that the value-level and type-level objects happen to be spelled the same in your source is just a coincidence! If you wanted to confuse your readers, you could perfectly well write
newtype Huey a = Louie a
newtype Louie a = Dewey a
newtype Dewey a = Huey a
where none of these three declarations are related to each other at all!
Now, we can finally tackle what goes wrong with test above: Integer and Int are not value constructors, so they can't be used in patterns. Remember -- the value level and type level are isolated, so you can't put type names in value definitions! By now, you might wish you had written test' instead:
test' :: Num a => a -> a
test' (x :: Integer) = x + 2
test' (x :: Int) = x + 1
test' (Zq x :: Zq a) = x
...but alas, it doesn't quite work like that. Value-level things aren't allowed to depend on type-level things. What you can do is to write separate functions at each of the Int, Integer, and Zq a types:
testInteger :: Integer -> Integer
testInteger x = x + 2
testInt :: Int -> Int
testInt x = x + 1
testZq :: Num a => Zq a -> Zq a
testZq (Zq x) = Zq x
Then we can call the appropriate one of these functions when we want to do a test. Since we're in a statically-typed language, exactly one of these functions is going to be applicable to any particular variable.
Now, it's a bit onerous to remember to call the right function, so Haskell offers a slight convenience: you can let the compiler choose one of these functions for you at compile time. This mechanism is the big idea behind classes. It looks like this:
class Testable a where test :: a -> a
instance Testable Integer where test = testInteger
instance Testable Int where test = testInt
instance Num a => Testable (Zq a) where test = testZq
Now, it looks like there's a single function called test which can handle any of Int, Integer, or numeric Zq's -- but in fact there are three functions, and the compiler is transparently choosing one for you. And that's an important insight. The type of test:
test :: Testable a => a -> a
...looks at first blush like it is a function that takes a value that could be any Testable type. But in fact, it's a function that can be specialized to any Testable type -- and then only takes values of that type! This difference explains yet another reason the original test function didn't work. You can't have multiple patterns with variables at different types, because the function only ever works on a single type at a time.
The ideas behind the classes NamedType and Testable above can be generalized a bit; if you do, you get the Typeable class suggested by hammar above.
I think now I've rambled more than enough, and likely confused more things than I've clarified, but leave me a comment saying which parts were unclear, and I'll do my best.
Is there a function that returns the type of an algebraic parameter (a 'show' for types)?
I think Data.Typeable may be what you're looking for.
Prelude> :m + Data.Typeable
Prelude Data.Typeable> typeOf (1 :: Int)
Int
Prelude Data.Typeable> typeOf (1 :: Integer)
Integer
Note that this will not work on any type, just those which have a Typeable instance.
Using the extension DeriveDataTypeable, you can have the compiler automatically derive these for your own types:
{-# LANGUAGE DeriveDataTypeable #-}
import Data.Typeable
data Foo = Bar
deriving Typeable
*Main> typeOf Bar
Main.Foo
I didn't quite get what you're trying to do in the second half of your question, but hopefully this should be of some help.

Resources