wrong use of logical operators in haskell? [duplicate] - haskell

other questions and problems, although similar, are not quite like this one. in this specific compiler error, the Haskell GHC won't compile the following code, for the following reason. I don't understand at all - the code is pretty straight forward.
--factorial
fact :: int -> int
fact 0 = 1
fact n | n > 0 = n * fact(n - 1)
main = print (fact 10)
(error:)
No instance for (Ord int) arising from a use of `>'
Possible fix:
add (Ord int) to the context of
the type signature for fact :: int -> int
In the expression: n > 0
In a stmt of a pattern guard for
an equation for `fact':
n > 0
In an equation for `fact': fact n | n > 0 = n * fact (n - 1)
Can you explain the problem to me?

Int is what you want:
fact :: int -> int
-->
fact :: Int -> Int
Since in Haskell, types need to begin with a cap.
Edit: Thank Yuras for commenting this:
Or if you want you could use a type class:
fact :: Integral a => a -> a
And you can name the type variable whichever you like, including int. Also, Num might fit your purpose better if you want to define factorial over general numbers.

Related

Besides as-pattern, what else can # mean in Haskell?

I am studying Haskell currently and try to understand a project that uses Haskell to implement cryptographic algorithms. After reading Learn You a Haskell for Great Good online, I begin to understand the code in that project. Then I found I am stuck at the following code with the "#" symbol:
-- | Generate an #n#-dimensional secret key over #rq#.
genKey :: forall rq rnd n . (MonadRandom rnd, Random rq, Reflects n Int)
=> rnd (PRFKey n rq)
genKey = fmap Key $ randomMtx 1 $ value #n
Here the randomMtx is defined as follows:
-- | A random matrix having a given number of rows and columns.
randomMtx :: (MonadRandom rnd, Random a) => Int -> Int -> rnd (Matrix a)
randomMtx r c = M.fromList r c <$> replicateM (r*c) getRandom
And PRFKey is defined below:
-- | A PRF secret key of dimension #n# over ring #a#.
newtype PRFKey n a = Key { key :: Matrix a }
All information sources I can find say that # is the as-pattern, but this piece of code is apparently not that case. I have checked the online tutorial, blogs and even the Haskell 2010 language report at https://www.haskell.org/definition/haskell2010.pdf. There is simply no answer to this question.
More code snippets can be found in this project using # in this way too:
-- | Generate public parameters (\( \mathbf{A}_0 \) and \(
-- \mathbf{A}_1 \)) for #n#-dimensional secret keys over a ring #rq#
-- for gadget indicated by #gad#.
genParams :: forall gad rq rnd n .
(MonadRandom rnd, Random rq, Reflects n Int, Gadget gad rq)
=> rnd (PRFParams n gad rq)
genParams = let len = length $ gadget #gad #rq
n = value #n
in Params <$> (randomMtx n (n*len)) <*> (randomMtx n (n*len))
I deeply appreciate any help on this.
That #n is an advanced feature of modern Haskell, which is usually not covered by tutorials like LYAH, nor can be found the the Report.
It's called a type application and is a GHC language extension. To understand it, consider this simple polymorphic function
dup :: forall a . a -> (a, a)
dup x = (x, x)
Intuitively calling dup works as follows:
the caller chooses a type a
the caller chooses a value x of the previously chosen type a
dup then answers with a value of type (a,a)
In a sense, dup takes two arguments: the type a and the value x :: a. However, GHC is usually able to infer the type a (e.g. from x, or from the context where we are using dup), so we usually pass only one argument to dup, namely x. For instance, we have
dup True :: (Bool, Bool)
dup "hello" :: (String, String)
...
Now, what if we want to pass a explicitly? Well, in that case we can turn on the TypeApplications extension, and write
dup #Bool True :: (Bool, Bool)
dup #String "hello" :: (String, String)
...
Note the #... arguments carrying types (not values). Those are something that exists at compile time, only -- at runtime the argument does not exist.
Why do we want that? Well, sometimes there is no x around, and we want to prod the compiler to choose the right a. E.g.
dup #Bool :: Bool -> (Bool, Bool)
dup #String :: String -> (String, String)
...
Type applications are often useful in combination with some other extensions which make type inference unfeasible for GHC, like ambiguous types or type families. I won't discuss those, but you can simply understand that sometimes you really need to help the compiler, especially when using powerful type-level features.
Now, about your specific case. I don't have all the details, I don't know the library, but it's very likely that your n represents a kind of natural-number value at the type level. Here we are diving in rather advanced extensions, like the above-mentioned ones plus DataKinds, maybe GADTs, and some typeclass machinery. While I can't explain everything, hopefully I can provide some basic insight. Intuitively,
foo :: forall n . some type using n
takes as argument #n, a kind-of compile-time natural, which is not passed at runtime. Instead,
foo :: forall n . C n => some type using n
takes #n (compile-time), together with a proof that n satisfies constraint C n. The latter is a run-time argument, which might expose the actual value of n. Indeed, in your case, I guess you have something vaguely resembling
value :: forall n . Reflects n Int => Int
which essentially allows the code to bring the type-level natural to the term-level, essentially accessing the "type" as a "value". (The above type is considered an "ambiguous" one, by the way -- you really need #n to disambiguate.)
Finally: why should one want to pass n at the type level if we then later on convert that to the term level? Wouldn't be easier to simply write out functions like
foo :: Int -> ...
foo n ... = ... use n
instead of the more cumbersome
foo :: forall n . Reflects n Int => ...
foo ... = ... use (value #n)
The honest answer is: yes, it would be easier. However, having n at the type level allows the compiler to perform more static checks. For instance, you might want a type to represent "integers modulo n", and allow adding those. Having
data Mod = Mod Int -- Int modulo some n
foo :: Int -> Mod -> Mod -> Mod
foo n (Mod x) (Mod y) = Mod ((x+y) `mod` n)
works, but there is no check that x and y are of the same modulus. We might add apples and oranges, if we are not careful. We could instead write
data Mod n = Mod Int -- Int modulo n
foo :: Int -> Mod n -> Mod n -> Mod n
foo n (Mod x) (Mod y) = Mod ((x+y) `mod` n)
which is better, but still allows to call foo 5 x y even when n is not 5. Not good. Instead,
data Mod n = Mod Int -- Int modulo n
-- a lot of type machinery omitted here
foo :: forall n . SomeConstraint n => Mod n -> Mod n -> Mod n
foo (Mod x) (Mod y) = Mod ((x+y) `mod` (value #n))
prevents things to go wrong. The compiler statically checks everything. The code is harder to use, yes, but in a sense making it harder to use is the whole point: we want to make it impossible for the user to try adding something of the wrong modulus.
Concluding: these are very advanced extensions. If you're a beginner, you will need to slowly progress towards these techniques. Don't be discouraged if you can't grasp them after only a short study, it does take some time. Make a small step at a time, solve some exercises for each feature to understand the point of it. And you'll always have StackOverflow when you are stuck :-)

Moving between instances of class like Num

The following might contain a stupid question but since I am somewhat new to Haskell I think I am in the clear. :)
I haven't got the faintest of how to express my question in valid Haskell lingo, but I think I can express it in English!
I my current state of naivety I believe there is some secret recipe that allows you to move between instance of a class, like instance of Num..
For example:
class Language l where
add :: Int -> Int -> l
jmp :: Int -> l
noop :: l
data Assembler where
Add :: Int -> Int -> Assembler
Jmp :: Int -> Assembler
Noop :: Assembler
instance Language Assembler where
add = Add
jmp = Jmp
noop = Noop
data C where
Plus :: Int -> Int -> C
Goto :: Int -> C
Void0 :: C
instance Language C where
add = Plus
jmp = Goto
noop = Void0
example :: C
example = add 1 2
Without changing the type of example how could I transform it to Assembler, I could write a function :: C -> Assembler, but that is not my question, rather I would like to ask if I could leverage the class/instance things instead to attain the same behaviour? Is there something here or I am I just buggering about?
When you talk about "some secret recipe that allows you to move between instance of a class, like instances of Num", you've perhaps gotten this impression by observing the behavior of numeric literals, and seeing that you can write:
> 2 :: Int
2
> 2 :: Integer
2
> 2 :: Double
2.0
> 2 :: Float
2.0
Here, it looks as if the integer 2 is allowed to "change types" between multiple instances of Num, right? So, why can't we do something similar with example?
> example :: C
Plus 1 2
> example :: Assembler
<interactive>:14:1: error:
• Couldn't match expected type ‘Assembler’ with actual type ‘C’
• In the expression: example :: Assembler
In an equation for ‘it’: it = example :: Assembler
Well, the reason has to do with the actual type of numeric literals. If we ask GHCi for the type of 2:
> :t 2
2 :: Num p => p
we see that the expression 2 doesn't actually have a specific (i.e., "monomorphic") integer type. Instead, 2 has a polymorphic type, Num p => p which can be thought of as "any type you like, as long as it has a Num instance". So, it's not that 2 is "changing types" in the above example. Rather, the type of 2 is being specialized from the polymorphic type Num p => p to a specific monomorphic type like Int or Double, depending on where it's used, in much the same way that the addition operator + can be specialized from its polymorphic type of:
(+) :: Num a => a -> a -> a
to any of:
(+) :: Int -> Int -> Int
(+) :: Double -> Double -> Double
etc.
when it's used in different contexts.
Getting back to your example, I think you were pretty quick to dismiss #boran's comment as some dirty trick that missed the point of your question. But, in fact, his comment is the answer to your question. The sort of "movement between instances of a class" that you're thinking of is accomplished by defining polymorphic expressions with type class constraints and then specializing to the desired instance.
Just as 2 :: Num p => p can be specialized to any Num instance, the polymorphic version of example':
example' :: Language l => l
example' = add 1 2
can be specialized to any Language instance:
> example' :: C
Plus 1 2
it :: C
> example' :: Assembler
Add 1 2
it :: Assembler
There's a whole paper about writing "tagless final" interpreters using this technique, and it's definitely worth reading.
Anyway, it's this specialization process that provides apparent movement between class instances. There's no other general, automatic mechanism for converting between arbitrary type class instances.

How to get a value in a tagged union data type in Haskell?

In Haskell, if I create a dataype like this:
data MyT = MyT Int deriving (Show)
myValue = MyT 42
I can get the Int value passing 'myValue' to a function and doing pattern matching:
getInt :: MyT -> Int
getInt (MyT n) = n
It seems to me that something simpler should be possible. Is there another way?
Also, I tried a lambda function:
(\(MyT n) -> n) myValue
It doesn't work and I don't understand why not.
I get the error:
The function `\ (MyT n) -> n' is applied to two arguments,
but its type `MyT -> Int' has only one
EDIT:
Of course, sepp2k below, is right about my lambda function working OK. I was doing:
(\(MyT n) -> n) myT 42
instead of
(\(MyT n) -> n) (myT 42)
If you want to get at the value of MyT inside a larger function without defining a helper function, you could either use case of or pattern matching in local variable definitions. Here are examples of that (assuming that g produces a MyT and f takes an Int):
Using case:
myLargerFunction x = f (case g x of MyT n => n)
Or with local variables:
myLargerFunction x = f myInt
where MyT myInt = g x
Or using let instead of where:
myLargerFunction x =
let MyT myInt = g x in
f myInt
Your lambda function should (and in fact does) also work fine. Your error message suggests that in your real code you're really doing something like (\(MyT n) -> n) myValue somethingElse (presumably by accident).
You can use the record syntax
data MyT = MyT {unMyT :: Int} deriving (Show)
which gives you the projection for free
unMyT :: MyT -> Int
This is nice if your data type has only one constructor (including newtypes). For data types involving more than one constrctor, projection functions tend to be unsafe (e.g., head,tail), and pattern matching is usually preferred instead. GHC checks for non-exhaustive patterns if you enable warnings, and can help to spot errors.
NewTypes create a distinct type and do not have an extra level of indirection like algebraic datatypes. See the Haskell report for more information:
http://www.haskell.org/onlinereport/decls.html#sect4.2.3
Prelude> newtype Age = Age { unAge :: Int } deriving (Show)
Prelude> let personAge = Age 42
Prelude> personAge
Age {unAge = 42}
Prelude> (unAge personAge) + 1
43
Using a lambda function:
Prelude> (\(Age age) -> age * 2) personAge
84

No instance for (Ord int) arising from a use of `>', Haskell

other questions and problems, although similar, are not quite like this one. in this specific compiler error, the Haskell GHC won't compile the following code, for the following reason. I don't understand at all - the code is pretty straight forward.
--factorial
fact :: int -> int
fact 0 = 1
fact n | n > 0 = n * fact(n - 1)
main = print (fact 10)
(error:)
No instance for (Ord int) arising from a use of `>'
Possible fix:
add (Ord int) to the context of
the type signature for fact :: int -> int
In the expression: n > 0
In a stmt of a pattern guard for
an equation for `fact':
n > 0
In an equation for `fact': fact n | n > 0 = n * fact (n - 1)
Can you explain the problem to me?
Int is what you want:
fact :: int -> int
-->
fact :: Int -> Int
Since in Haskell, types need to begin with a cap.
Edit: Thank Yuras for commenting this:
Or if you want you could use a type class:
fact :: Integral a => a -> a
And you can name the type variable whichever you like, including int. Also, Num might fit your purpose better if you want to define factorial over general numbers.

How to declare function (type misunderstanding Maybe)

I need a function which works like:
some :: (Int, Maybe Int) -> Int
some a b
| b == Nothing = 0
| otherwise = a + b
Use cases:
some (2,Just 1)
some (3,Nothing)
map some [(2, Just 1), (3,Nothing)]
But my code raise the error:
The equation(s) for `some' have two arguments,
but its type `(Int, Maybe Int) -> Int' has only one
I don't understand it.
Thanks in advance.
When you write
foo x y = ...
That is notation for a curried function, with a type like:
foo :: a -> b -> c
You have declared your function to expect a tuple, so you must write it:
some :: (Int, Maybe Int) -> Int
some (x, y) = ...
But Haskell convention is usually to take arguments in the former curried form. Seeing funcitons take tuples as arguments is very rare.
For the other part of your question, you probably want to express it with pattern matching. You could say:
foo :: Maybe Int -> Int
foo Nothing = 0
foo (Just x) = x + 1
Generalizing that to the OP's question is left as an exercise for the reader.
Your error doesn't come from a misunderstanding of Maybe: The type signature of some indicates that it takes a pair (Int, Maybe Int), while in your definition you provide it two arguments. The definition should thus begin with some (a,b) to match the type signature.
One way to fix the problem (which is also a bit more idiomatic and uses pattern matching) is:
some :: (Int, Maybe Int) -> Int
some (a, Nothing) = a
some (a, Just b) = a + b
It's also worth noting that unless you have a really good reason for using a tuple as input, you should probably not do so. If your signature were instead some :: Int -> Maybe Int -> Int, you'd have a function of two arguments, which can be curried. Then you'd write something like
some :: Int -> Maybe Int -> Int
some a Nothing = a
some a (Just b) = a + b
Also, you might want to add the following immediate generalization: All Num types are additive, so you might aswell do
some :: (Num n) => n -> Maybe n -> n
some a Nothing = a
some a (Just b) = a + b
(I've violated the common practice of using a, b, c... for type variables so as not to confuse the OP since he binds a and b to the arguments of some).

Resources