Haskell Type Misunderstanding assigning variables - haskell

Complete noob to haskell here, i'm trying to make this following piece of code work:
It's intent is to take the first exp elements of a list, concatenate them, then call the same function again.
order ( i ) (l1)(l2) =
do exp <- (2 ^ i)
l <- (take exp l1) ++ (take exp l2 ) ++ (order (i+1) (drop exp l1) (drop exp l2));
return l
I'm sure this is far from idiomatic haskell, but you have to start some where though.
The error I am getting is on the
exp <- (2 ^ i )
saying that
No instance for (Num [Int])
arising from a use of `^'
Possible fix: add an instance declaration for (Num [Int])
which i am really unsure what this exactly means. Isn't both 2 and i integers, and then applying the exponentiation function will result in an integer?
Thanks!

I've rewritten your code as follows and added a main.
order _ [] [] = []
order i l1 l2 =
(take exp l1) ++ (take exp l2)
++ (order (i+1) (drop exp l1) (drop exp l2))
where
exp = 2^i
main = print $ order 1 [1,2,3,4] [3,4,5,6]
The first mistake you make is that your recursion doesn't terminate as order will always call itself again. The second mistake is in the use of do, this introduces a monad and considering you are new to Haskell, I would stay clear a bit. Use it only for I/O for now.
I hope this helps.
P.S: The error message you are getting is saying that a list of Int is used in a numeric way and there is no default implementation for that. This is probably caused by the do where the monad is over lists, but I'll leave it to cracks in Haskell to give an exact explanation.

All statements in a do block must belong to the same monad. This includes the right hand side of <- bindings. Therefore, because the right hand side of the second statement take exp l1 ++ ... is a list, the compiler infers that the type of 2^i must be a list as well.
This is because <- does more than just assign variables. In the case of the list monad, it sequentially binds the variable on the left to each element of the list on the right.
If you just want to bind a variable without any additional effects in a do block, you should use a let binding instead of <-.
do let exp = 2^i
l <- take exp l1 ++ ...
return l
That said, the use of do notation here is redundant. The monad laws guarantee that do x <- m; return x is the same as just m, so you can just write it directly as
order i l1 l2 = take exp l1 ++ ...
where exp = 2^i

In addition to Bryan's points, I think I can help explain the reason you got that specific error.
The big reason is that exp <- 2 ^ i in a do block does not mean "let exp be a name for the value of 2 ^ i" (You would express that meaning in a do block as let exp = 2 ^ i, but a do block isn't really what you want here anyway).
What exp <- 2 ^ i means is "let exp be a name for a value yielded by the monadic value 2 ^ i". Try reading the <- as "comes from" rather than "is". What exactly "comes from" means depends on the monad involved. So for this line to mean something, 2 ^ i must be a value in some kind of monad. Specifically, it's type is something like Monad m => m a, for unknown m and a.
Because the ^ operator works on numeric values, it returns something of type Num a => a. So that allows us to figure out that 2 ^ i should be something of type (Monad m, Num (m a)) => m a, for unknown m and a.
exp is extracted from this mystery m a, so it is of type a. The next line includes expressions like take exp l1. take requires its first argument to be of type Int, and so exp must be of type Int, and so we can tell that that unknown a we were working with must be Int. So 2 ^ i is now known to be of type (Monad m, Num (m Int)) => m Int; it is some sort of monadic integer.
In this line you also have l <- (take exp l1) ++ .... So l also "comes from" some sort of monadic value. The right hand side can be seen to be some sort of list (due to the use of ++, take, and drop). The monad involved in a do block must be the same throughout, and the list type constructor is indeed a monad. So if (take exp l1) ++ ... is a list of something, then 2 ^ i must also be a list of something.
So now we have 2 ^ i being of type [Int] (we originally knew it was m a; the m is the list type constructor [], and the a is Int). But we also know (from the use of the ^ operator) that it must be a member of the Num type class. There is no instance of Num for [Int], which is exactly the error you got.
That's just one of many inconsistencies that can be derived from the code you wrote; it's just the first one that GHC happened to encounter while trying to analyse it.

Related

Generate injective functions with QuickCheck?

I'm using QuickCheck to generate arbitrary functions, and I'd like to generate arbitrary injective functions (i.e. f a == f b if and only if a == b).
I thought I had it figured out:
newtype Injective = Injective (Fun Word Char) deriving Show
instance Arbitrary Injective where
arbitrary = fmap Injective fun
where
fun :: Gen (Fun Word Char)
fun = do
a <- arbitrary
b <- arbitrary
arbitrary `suchThat` \(Fn f) ->
(f a /= f b) || (a == b)
But I'm seeing cases where the generated function maps distinct inputs to the same output.
What I want:
f such that for all inputs a and b, either f a does not equal f b or a equals b.
What I think I have:
f such that there exist inputs a and b where either f a does not equal f b or a equals b.
How can I fix this?
You've correctly identified the problem: what you're generating is functions with the property ∃ a≠b. f a≠f b (which is readily true for most random functions anyway), whereas what you want is ∀ a≠b. f a≠f b. That is a much more difficult property to ensure, because you need to know about all the other function values for generating each individual one.
I don't think this is possible to ensure for general input types, however for word specifically what you can do is “fake” a function by precomputing all the output values sequentially, making sure that you don't repeat one that has already been done, and then just reading off from that predetermined chart. It requires a bit of laziness fu to actually get this working:
import qualified Data.Set as Set
newtype Injective = Injective ([Char] {- simply a list without duplicates -})
deriving Show
instance Arbitrary Injective where
arbitrary = Injective . lazyNub <$> arbitrary
lazyNub :: Ord a => [a] -> [a]
lazyNub = go Set.empty
where go _ [] = []
go forbidden (x:xs)
| x `Set.member` forbidden = go forbidden xs
| otherwise = x : go (Set.insert x forbidden) xs
This is not very efficient, and may well not be ok for your application, but it's probably the best you can do.
In practice, to actually use Injective as a function, you'll want to wrap the values in a suitable structure that has only O (log n) lookup time. Unfortunately, Data.Map.Lazy is not lazy enough, you may need to hand-bake something like a list of exponentially-growing maps.
There's also the concern that for some insufficiently big result types, it is just not possible to generate injective functions because there aren't enough values available. In fact as Joseph remarked, this is the case here. The lazyNub function will go into an infinite loop in this case. I'd say for a QuickCheck this is probably ok though.

Haskell's (<-) in Terms of the Natural Transformations of Monad

So I'm playing around with the hasbolt module in GHCi and I had a curiosity about some desugaring. I've been connecting to a Neo4j database by creating a pipe as follows
ghci> pipe <- connect $ def {credentials}
and that works just fine. However, I'm wondering what the type of the (<-) operator is (GHCi won't tell me). Most desugaring explanations describe that
do x <- a
return x
desugars to
a >>= (\x -> return x)
but what about just the line x <- a?
It doesn't help me to add in the return because I want pipe :: Pipe not pipe :: Control.Monad.IO.Class.MonadIO m => m Pipe, but (>>=) :: Monad m => m a -> (a -> m b) -> m b so trying to desugar using bind and return/pure doesn't work without it.
Ideally it seems like it'd be best to just make a Comonad instance to enable using extract :: Monad m => m a -> a as pipe = extract $ connect $ def {creds} but it bugs me that I don't understand (<-).
Another oddity is that, treating (<-) as haskell function, it's first argument is an out-of-scope variable, but that wouldn't mean that
(<-) :: a -> m b -> b
because not just anything can be used as a free variable. For instance, you couldn't bind the pipe to a Num type or a Bool. The variable has to be a "String"ish thing, except it never is actually a String; and you definitely can't try actually binding to a String. So it seems as if it isn't a haskell function in the usual sense (unless there is a class of functions that take values from the free variable namespace... unlikely). So what is (<-) exactly? Can it be replaced entirely by using extract? Is that the best way to desugar/circumvent it?
I'm wondering what the type of the (<-) operator is ...
<- doesn't have a type, it's part of the syntax of do notation, which as you know is converted to sequences of >>= and return during a process called desugaring.
but what about just the line x <- a ...?
That's a syntax error in normal haskell code and the compiler would complain. The reason the line:
ghci> pipe <- connect $ def {credentials}
works in ghci is that the repl is a sort of do block; you can think of each entry as a line in your main function (it's a bit more hairy than that, but that's a good approximation). That's why you need (until recently) to say let foo = bar in ghci to declare a binding as well.
Ideally it seems like it'd be best to just make a Comonad instance to enable using extract :: Monad m => m a -> a as pipe = extract $ connect $ def {creds} but it bugs me that I don't understand (<-).
Comonad has nothing to do with Monads. In fact, most Monads don't have any valid Comonad instance. Consider the [] Monad:
instance Monad [a] where
return x = [x]
xs >>= f = concat (map f xs)
If we try to write a Comonad instance, we can't define extract :: m a -> a
instance Comonad [a] where
extract (x:_) = x
extract [] = ???
This tells us something interesting about Monads, namely that we can't write a general function with the type Monad m => m a -> a. In other words, we can't "extract" a value from a Monad without additional knowledge about it.
So how does the do-notation syntax do {x <- [1,2,3]; return [x,x]} work?
Since <- is actually just syntax sugar, just like how [1,2,3] actually means 1 : 2 : 3 : [], the above expression actually means [1,2,3] >>= (\x -> return [x,x]), which in turn evaluates to concat (map (\x -> [[x,x]]) [1,2,3])), which comes out to [1,1,2,2,3,3].
Notice how the arrow transformed into a >>= and a lambda. This uses only built-in (in the typeclass) Monad functions, so it works for any Monad in general.
We can pretend to extract a value by using (>>=) :: Monad m => m a -> (a -> m b) -> m b and working with the "extracted" a inside the function we provide, like in the lambda in the list example above. However, it is impossible to actually get a value out of a Monad in a generic way, which is why the return type of >>= is m b (in the Monad)
So what is (<-) exactly? Can it be replaced entirely by using extract? Is that the best way to desugar/circumvent it?
Note that the do-block <- and extract mean very different things even for types that have both Monad and Comonad instances. For instance, consider non-empty lists. They have instances of both Monad (which is very much like the usual one for lists) and Comonad (with extend/=>> applying a function to all suffixes of the list). If we write a do-block such as...
import qualified Data.List.NonEmpty as N
import Data.List.NonEmpty (NonEmpty(..))
import Data.Function ((&))
alternating :: NonEmpty Integer
alternating = do
x <- N.fromList [1..6]
-x :| [x]
... the x in x <- N.fromList [1..6] stands for the elements of the non-empty list; however, this x must be used to build a new list (or, more generally, to set up a new monadic computation). That, as others have explained, reflects how do-notation is desugared. It becomes easier to see if we make the desugared code look like the original one:
alternating :: NonEmpty Integer
alternating =
N.fromList [1..6] >>= \x ->
-x :| [x]
GHCi> alternating
-1 :| [1,-2,2,-3,3,-4,4,-5,5,-6,6]
The lines below x <- N.fromList [1..6] in the do-block amount to the body of a lambda. x <- in isolation is therefore akin to a lambda without body, which is not a meaningful thing.
Another important thing to note is that x in the do-block above does not correspond to any one single Integer, but rather to all Integers in the list. That already gives away that <- does not correspond to an extraction function. (With other monads, the x might even correspond to no values at all, as in x <- Nothing or x <- []. See also Lazersmoke's answer.)
On the other hand, extract does extract a single value, with no ifs or buts...
GHCi> extract (N.fromList [1..6])
1
... however, it is really a single value: the tail of the list is discarded. If we want to use the suffixes of the list, we need extend/(=>>)...
GHCi> N.fromList [1..6] =>> product =>> sum
1956 :| [1236,516,156,36,6]
If we had a co-do-notation for comonads (cf. this package and the links therein), the example above might get rewritten as something in the vein of:
-- codo introduces a function: x & f = f x
N.fromList [1..6] & codo xs -> do
ys <- product xs
sum ys
The statements would correspond to plain values; the bound variables (xs and ys), to comonadic values (in this case, to list suffixes). That is exactly the opposite of what we have with monadic do-blocks. All in all, as far as your question is concerned, switching to comonads just swaps which things we can't refer to outside of the context of a computation.

Type Specification in a Where Clause

I'm trying to do something very simple as part of a homework. All I need to do is write a function that takes in a list of 2-tuples of numbers representing base and height lengths for triangles, and return a list of the areas corresponding to those triangles. One of the requirements is that I do that by defining a function and declaring its type in a where clause. Everything I've tried so far fails to compile, here's what I've got:
calcTriangleAreas xs = [triArea x | x<-xs]
where triArea:: (Num, Num) -> Num --this uses 4 preceding spaces
triArea (base, height) = base*height/2
This fails with the error The type signature for ‘triArea’ lacks an accompanying binding, which to me sounds like triArea is not defined inside of the where-clause. Okay, so let's indent it to match the where:
calcTriangleAreas xs = [triArea x | x<-xs]
where triArea:: (Num, Num) -> Num --this uses 4 preceding spaces
triArea (base, height) = base*height/2 --... and so does this
This one fails to compile the particularly uninformative error message parse error on input triArea. Just for fun, let's try indenting it a bit more, because idk what else to do:
calcTriangleAreas xs = [triArea x | x<-xs]
where triArea:: (Num, Num) -> Num --this uses 4 preceding spaces
triArea (base, height) = base*height/2 --this has 8
but, no dice, fails with the same parse error message. I tried replacing the spacing in each of these with equivalent, 4-space tabs, but that didn't
help. The first two produce the same errors with tabs as with spaces, but the last one, shown here:
calcTriangleAreas xs = [triArea x | x<-xs]
where triArea:: (Num, Num) -> Num --this uses a preceding tab character
triArea (base, height) = base*height/2 --this has 2
gives the error message
Illegal type signature: ‘(Num, Num) -> Num triArea (base, height)’
Perhaps you intended to use ScopedTypeVariables
In a pattern type-signature
and I have no idea what that's trying to say, but it seems to be ignoring newlines all of a sudden. I've been reading through "Learn You a Haskell", and I'm supposed to be able to do this with the information presented in the first three chapters, but I've scoured those and they never specify the type of a functioned defined in a where clause in those chapters. For the record, their examples seem to be irreverent of spacing, and I copied the style of one of them:
calcTriangleAreas xs = [triArea x | x<-xs]
where triArea:: (Num, Num) -> Num --4 preceding spaces
triArea (base, height) = base*height/2 --10 preceding spaces
but this also failed to compile, spitting out the utterly incomprehensible error message:
Expecting one more argument to ‘Num’
The first argument of a tuple should have kind ‘*’,
but ‘Num’ has kind ‘* -> GHC.Prim.Constraint’
In the type signature for ‘triArea’: triArea :: (Num, Num) -> Num
In an equation for ‘calcTriangleAreas’:
calcTriangleAreas xs
= [triArea x | x <- xs]
where
triArea :: (Num, Num) -> Num
triArea (base, height) = base * height / 2
I can't find anything when I google/hoogle it, and I've looked at this question, but not only is it showing haskell far too
advanced for me to read, but based on the content I don't believe they're having the same problem as me. I've tried specifying the type of calcTriangleAreas, and I've tried aliasing the types in the specification for triArea to be Floating and frankly I'm at the end of my rope. The top line of my file is module ChapterThree where, but beyond that the code I've shown in every example is the entire file.
I'm working on 32-bit Linux Mint 18, and I'm compiling with ghc ChapterThree.hs Chapter3UnitTests.hs -o Test, where ChapterThree.hs is my file and the unit tests are given by my teacher so I can easily tell if my program works (It never gets to the compilation step for ChapterThreeUnitTests.hs, so I didn't think the content would be important), and my ghc version is 7.10.3.
EDIT: Note that if I just remove the type specification altogether, everything compiles just fine, and that function passes all of its associated unit tests.
Please, save me from my madness.
Your last example is correct, but the type you wrote doesn't make sense. Num is a class constraint not a type. You probably wanted to write:
calcTriangleAreas xs = [triArea x | x<-xs]
where triArea:: Num a => (a, a) -> a
triArea (base, height) = base*height/2
The rule is: assignments must be aligned.
Moreover (/) requires the Fractional class:
calcTriangleAreas xs = [triArea x | x<-xs]
where triArea:: Fractional a => (a, a) -> a
triArea (base, height) = base*height/2
Note that the indentation level is not related in any way with the indentation level of the where. For example you could write that code in this way:
calcTriangleAreas xs = [triArea x | x<-xs] where
triArea:: Fractional a => (a, a) -> a
triArea (base, height) = base*height/2
The indentation level is defined by the first assignment in a where/let or the first line of a do block. All the other lines must align with that one.
So all of these are correct:
f x = y where
a = b
y = ...
f x = y
where a = b
y = ...
f x = y
where
a = b
y = ...
spitting out the utterly incomprehensible error message:
Expecting one more argument to ‘Num’
The first argument of a tuple should have kind ‘*’,
but ‘Num’ has kind ‘* -> GHC.Prim.Constraint’
To complement Bakuriu's answer, let me decode that for you.
The error says that -- line by line:
Num is expecting one more argument -- we should write Num a from some a
A tuple type such as (,) expects a type as argument. The statement "should have kind *" means "should be a type". The kinding system of Haskell associates * as the "kind of types". We have e.g. Int :: *, String :: *, and (Maybe Char, [Int]) :: *. Unary type constructors such as Maybe and [] are not types, but functions from types to types. We write Maybe :: *->* and [] :: *->*. Their kind *->* makes it possible to state that, since Maybe :: *->* and Char :: *, we have Maybe Char :: * ("is a type") similarly to ordinary value-level functions. The pair type constructor has kind (,) :: *->*->*: it expects two types and provides a type.
Num has kind *-> Constraint. This means that, for every type T, the kind of Num T will be Constraint, which is not * as (,) expects. This triggers a kind error. The kind Constraint is given to typeclass constraints such as Eq Int, Ord Bool, or Num Int. These are not types, but are requirements on types. When we use (+) :: Num a => a->a->a we see that (+) works on any type a, as long as that type satisfies Num a, i.e. is numeric. Since Num T is not a type, we can not write Maybe (Num T) or [Num T], we can only write e.g. Maybe a and require in the context that a belongs to typeclass Num.

Haskell type dessignation

I have to dessignate types of 2 functions(without using compiler :t) i just dont know how soudl i read these functions to make correct steps.
f x = map -1 x
f x = map (-1) x
Well i'm a bit confuse how it will be parsed
Function application, or "the empty space operator" has higher precedence than any operator symbol, so the first line parses as f x = map - (1 x), which will most likely1 be a type error.
The other example is parenthesized the way it looks, but note that (-1) desugars as negate 1. This is an exception from the normal rule, where operator sections like (+1) desugar as (\x -> x + 1), so this will also likely1 be a type error since map expects a function, not a number, as its first argument.
1 I say likely because it is technically possible to provide Num instances for functions which may allow this to type check.
For questions like this, the definitive answer is to check the Haskell Report. The relevant syntax hasn't changed from Haskell 98.
In particular, check the section on "Expressions". That should explain how expressions are parsed, operator precedence, and the like.
These functions do not have types, because they do not type check (you will get ridiculous type class constraints). To figure out why, you need to know that (-1) has type Num n => n, and you need to read up on how a - is interpreted with or without parens before it.
The following function is the "correct" version of your function:
f x = map (subtract 1) x
You should be able to figure out the type of this function, if I say that:
subtract 1 :: Num n => n -> n
map :: (a -> b) -> [a] -> [b]
well i did it by my self :P
(map) - (1 x)
(-)::Num a => a->a->->a
1::Num b=> b
x::e
map::(c->d)->[c]->[d]
map::a
a\(c->d)->[c]->[d]
(1 x)::a
1::e->a
f::(Num ((c->d)->[c]->[d]),Num (e->(c->d)->[c]->[d])) => e->(c->d)->[c]->[d]

Data constructor in template haskell

I'm trying to create the ring Z/n (like normal arithmetic, but modulo some integer). An example instance is Z4:
instance Additive.C Z4 where
zero = Z4 0
(Z4 x) + (Z4 y) = Z4 $ (x + y) `mod` 4
And so on for the ring. I'd like to be able to quickly generate these things, and I think the way to do it is with template haskell. Ideally I'd like to just go $(makeZ 4) and have it spit out the code for Z4 like I defined above.
I'm having a lot of trouble with this though. When I do genData n = [d| data $n = $n Integer] I get "parse error in data/newtype declaration". It does work if I don't use variables though: [d| data Z5 = Z5 Integer |], which must mean that I'm doing something weird with the variables. I'm not sure what though; I tried constructing them via newName and that didn't seem to work either.
Can anyone help me with what's going on here?
The Template Haskell documentation lists the things you are allowed to splice.
A splice can occur in place of
an expression; the spliced expression must have type Q Exp
an type; the spliced expression must have type Q Typ
a list of top-level declarations; the spliced expression must have type Q [Dec]
In both occurrences of $n, however, you're trying to splice a name.
This means you can't do this using quotations and splices. You'll have to build declaration using the various combinators available in the Language.Haskell.TH module.
I think this should be equivalent to what you're trying to do.
genData :: Name -> Q [Dec]
genData n = fmap (:[]) $ dataD (cxt []) n []
[normalC n [strictType notStrict [t| Integer |]]] []
Yep, it's a bit ugly, but there you go. To use this, call it with a fresh name, e.g.
$(genData (mkName "Z5"))

Resources