GHC won't run this function, but does compile it - function

This is the code:
finde_f x =
if (x-2) mod 3 /= 0
then 1
else x - (x-2)/3
These are the errors during run-time:
*Main> finde_f 6
<interactive>:170:1:
No instance for (Fractional ((a10 -> a10 -> a10) -> a20 -> a0))
arising from a use of `finde_f'
Possible fix:
add an instance declaration for
(Fractional ((a10 -> a10 -> a10) -> a20 -> a0))
In the expression: finde_f 6
In an equation for `it': it = finde_f 6
<interactive>:170:9:
No instance for (Num ((a10 -> a10 -> a10) -> a20 -> a0))
arising from the literal `6'
Possible fix:
add an instance declaration for
(Num ((a10 -> a10 -> a10) -> a20 -> a0))
In the first argument of `finde_f', namely `6'
In the expression: finde_f 6
In an equation for `it': it = finde_f 6
I'm not sure what is happening here. I hope you can help me understand why this (very) simple function doesn't run. Is it because of mod or /? How can I fix this?
Edit: After changing to mod:
*Main> finde_f 3
<interactive>:12:1:
No instance for (Integral a0) arising from a use of `finde_f'
The type variable `a0' is ambiguous
Possible fix: add a type signature that fixes these type variable(s)
Note: there are several potential instances:
instance Integral Int -- Defined in `GHC.Real'
instance Integral Integer -- Defined in `GHC.Real'
instance Integral GHC.Types.Word -- Defined in `GHC.Real'
In the expression: finde_f 3
In an equation for `it': it = finde_f 3
<interactive>:12:9:
No instance for (Num a0) arising from the literal `3'
The type variable `a0' is ambiguous
Possible fix: add a type signature that fixes these type variable(s)
Note: there are several potential instances:
instance Num Double -- Defined in `GHC.Float'
instance Num Float -- Defined in `GHC.Float'
instance Integral a => Num (GHC.Real.Ratio a)
-- Defined in `GHC.Real'
...plus three others
In the first argument of `finde_f', namely `3'
In the expression: finde_f 3
In an equation for `it': it = finde_f 3
Full-code, with correction:
-- Continuous Fraction -------------------------------------------------------------------
-- A --
cont_frac n d k =
if k == 1
then (n k) / (d k)
else (n k) / ((d k) + (cont_frac n d (k-1)))
-- B --
cont_frac_iter n d k count =
if count == k
then (n count) / (d count)
else (n count) / ((d count) + (cont_frac_iter n d k (count+1)))
-- e-2 Continuous Fraction ---------------------------------------------------------------
finde_cf k =
2 + (cont_frac_iter (\x -> 1) finde_f (k) (1))
-- Auxiliary Function --
finde_f x =
if mod (x-2) 3 /= 0
then 1
else fromIntegral x - (fromIntegral x-2)/3

mod is a prefix function, but you use it as infix.
Use:
mod (x-2) 3 /= 0 --prefix
or
(x-2) `mod` 3 /= 0 --infix
UPDATED
You try to use Integral with Fractional
> :t (/)
(/) :: Fractional a => a -> a -> a
> :t mod
mod :: Integral a => a -> a -> a
So, just convert numerals, like this:
> :t fromIntegral
fromIntegral :: (Integral a, Num b) => a -> b
... else fromIntegral x - (fromIntegral x-2)/3

Related

Why cant i have a "equal" rational function

i am very new to the haskell and have a question about Eq.
data Rat = Rat Integer Integer
normaliseRat :: Rat -> Rat
normaliseRat (Rat x y)
|x < 0 && y < 0 = Rat (-x) (-y)
|otherwise = Rat (x `div`(gcd x y)) (y `div` (gcd x y))
So i have a func normaliseRat. And what i need is an instance of Eq and Ord. Of course, Rat 2 4 == Rat 1 2 should be valid.
Thanks for help
Haskell doesn't support function overloading. But (==) isn't a function; it's declared as a typeclass method, so any type-specific implementations of the method must be defined within an instance declaration, like so:
instance Eq Rat where
(Rat x y) == (Rat n m) = x * m == y * n
(x/y == n/m is equivalent, after cross multiplying, to x * m == y * n; multiplication is more efficient and has none of accuracy issues that division would introduce.)
The same applies to Ord, except you have your choice of implementing (<=) or compare. (Given either of those, default definitions for the other comparison methods will work.)
instance Ord Rat where
-- I leave fixing this to accommodate negative numbers
-- correctly as an exercise.
(Rat x y) <= (Rat n m) = (x * m) <= (y * n)
As a typeclass method, (==) is really an entire family of functions, indexed by the type it's being used with. The purpose of the instance declaration is not to redefine the method, but to add a new function to that family.
If you enable the TypeApplications extension, you can view (==) as a mapping from a type to a function.
> :t (==)
(==) :: Eq a => a -> a -> Bool
> :t (==) #Int
(==) #Int :: Int -> Int -> Bool
Without a type application, Haskell's type checker automatically figures out which function to use:
> (==) 'c' 'd'
False
> (==) 3 5
False
but you can be explicit:
> (==) #Char 'c 'd'
False
> (==) #Char 3 5
<interactive>:9:12: error:
• No instance for (Num Char) arising from the literal ‘3’
• In the second argument of ‘(==)’, namely ‘3’
In the expression: (==) #Char 3 5
In an equation for ‘it’: it = (==) #Char 3 5

Abstracting Function in Haskell

I am currently taking a class in Haskell and am having a bit of trouble understanding how functions are passed as parameters. For this assignment, we were tasked with creating a program that would evaluate expressions. To reduce boiler plating, I wanted to abstract the function by creating a helper function that would take in an operator as an input and return the result
Main Function:
eval :: EDict -> Expr -> Maybe Double
eval _ (Val x) = Just x
eval d (Var i) = find d i
eval d (Add x y) = evalOp d (+) x y
eval d (Mul x y) = evalOp d (*) x y
eval d (Sub x y) = evalOp d (-) x y
Helper Function:
evalOp:: EDict -> ((Num a) => a -> a -> a) -> Expr -> Expr -> Maybe Double
evalOp d op x y =
let r = eval d x
s = eval d y
in case (r, s) of
(Just m, Just n) -> Just (m `op` n)
_ -> Nothing
Other definitions
data Expr
= Val Double
| Add Expr Expr
| Mul Expr Expr
| Sub Expr Expr
| Dvd Expr Expr
| Var Id
| Def Id Expr Expr
deriving (Eq, Show)
type Dict k d = [(k,d)]
define :: Dict k d -> k -> d -> Dict k d
define d s v = (s,v):d
find :: Eq k => Dict k d -> k -> Maybe d
find [] _ = Nothing
find ( (s,v) : ds ) name | name == s = Just v
| otherwise = find ds name
type EDict = Dict String Double
I looked into how +,-, and * are to be passed into other functions and found that these operators are defined by the following definition:
ghci> :t (*)
(*) :: (Num a) => a -> a -> a
However, when I run my code I get the following compilation error:
Illegal polymorphic or qualified type: Num a => a -> a -> a
Perhaps you intended to use RankNTypes or Rank2Types
In the type signature for ‘evalOp’:
evalOp :: EDict
-> ((Num a) => a -> a -> a) -> Expr -> Expr -> Maybe Double
I am not really sure why this is happening as I gave my function the proper parameters as defined by Haskell. Any help would be greatly appreciated as I am still very new to the language.
Right now, your Expr data type is constrained to Double-valued expressions, so there is no need to deal with polymorphism.
evalOp:: EDict -> (Double -> Double -> Double) -> Expr -> Expr -> Maybe Double
evalOp d op x y =
let r = eval d x
s = eval d y
in case (r, s) of
(Just m, Just n) -> Just (m `op` n)
_ -> Nothing
(+) :: Num a => a -> a -> a is a valid argument for evalOp, because its type can be "restricted" to Double -> Double -> Double.
> let f :: Double -> Double -> Double; f = (+)
> f 3 5
8.0
If your expression type were parameterized, then you would put a Num a constraint on your functions (not just on the arguments that involve a, because you want the same a throughout the function).
data Expr a
= Val a
| Add (Expr a) (Expr a)
| Mul (Expr a) (Expr a)
| Sub (Expr a) (Expr a)
| Dvd (Expr a) (Expr a)
| Var Id
| Def Id (Expr a) (Expr a)
deriving (Eq, Show)
type EDict a = Dict String a
evalOp:: Num a => EDict a -> (a -> a -> a) -> Expr a -> Expr a -> Maybe a
evalOp d op x y =
let r = eval d x
s = eval d y
in case (r, s) of
(Just m, Just n) -> Just (m `op` n)
_ -> Nothing
eval :: Num a => EDict a -> Expr a -> Maybe a
eval _ (Val x) = Just x
eval d (Var i) = find d i
eval d (Add x y) = evalOp d (+) x y
eval d (Mul x y) = evalOp d (*) x y
eval d (Sub x y) = evalOp d (-) x y
The error is telling you that you cannot nest a type qualifier inside one of the types in your function chain. Instead, put all of the qualifiers at the beginning of the type signature:
evalOp:: (Num a) => EDict -> (a -> a -> a) -> Expr -> Expr -> Maybe Double
See Haskell - Illegal Polymorphic type? for a more thorough discussion.

How can two similar functions have different polymorphic types in Haskell?

Im pretty much new to Haskell, so if Im missing key concept, please point it out.
Lets say we have these two functions:
fact n
| n == 0 = 1
| n > 0 = n * (fact (n - 1))
The polymorphic type for fact is (Eq t, Num t) => t -> t Because n is used in the if condition and n must be of valid type to do the == check. Therefor t must be a Number and t can be of any type within class constraint Eq t
fib n
| n == 1 = 1
| n == 2 = 1
| n > 2 = fib (n - 1) + fib (n - 2)
Then why is the polymorphic type of fib is (Eq a, Num a, Num t) => a -> t?
I don't understand, please help.
Haskell always aims to derive the most generic type signature.
Now for fact, we know that the type of the output, should be the same as the type of the input:
fact n | n == 0 = 1
| n > 0 = n * (fact (n - 1))
This is due to the last line. We use n * (fact (n-1)). So we use a multiplication (*) :: a -> a -> a. Multiplication thus takes two members of the same type and returns a member of that type. Since we multiply with n, and n is input, the output is of the same type as the input. Since we use n == 0, we know that (==) :: Eq a => a -> a -> Bool so that means that that input type should have Eq a =>, and furthermore 0 :: Num a => a. So the resulting type is fact :: (Num a, Eq a) => a -> a.
Now for fib, we see:
fib n | n == 1 = 1
| n == 2 = 1
| n > 2 = fib (n - 1) + fib (n - 2)
Now we know that for n, the type constraints are again Eq a, Num a, since we use n == 1, and (==) :: Eq a => a -> a -> Bool and 1 :: Num a => a. But the input n is never directly used in the output. Indeed, the last line has fib (n-1) + fib (n-2), but here we use n-1 and n-2 as input of a new call. So that means we can safely asume that the input type and the output type act independently. The output type, still has a type constraint: Num t: this is since we return 1 for the first two cases, and 1 :: Num t => t, and we also return the addition of two outputs: fib (n-1) + fib (n-2), so again (+) :: Num t => t -> t -> t.
The difference is that in fact, you use the argument directly in an arithmetic expression which makes up the final result:
fact n | ... = n * ...
IOW, if you write out the expanded arithmetic expression, n appears in it:
fact 3 ≡ n * (n-1) * (n-2) * 1
This fixes that the argument must have the same type as the result, because
(*) :: Num n => n -> n -> n
Not so in fib: here the actual result is only composed of literals and of sub-results. IOW, the expanded expression looks like
fib 3 ≡ (1 + 1) + 1
No n in here, so no unification between argument and result required.
Of course, in both cases you also used n to decide how this arithmetic expression looks, but for that you've just used equality comparisons with literals, whose type is not connected to the final result.
Note that you can also give fib a type-preservig signature: (Eq a, Num a, Num t) => a -> t is strictly more general than (Eq t, Num t) => t -> t. Conversely, you can make a fact that doesn't require input- and output to be the same type, by following it with a conversion function:
fact' :: (Eq a, Integral a, Num t) => a -> t
fact' = fromIntegral . fact
This doesn't make a lot of sense though, because Integer is pretty much the only type that can reliably be used in fact, but to achieve that in the above version you need to start out with Integer. Hence if anything, you should do the following:
fact'' :: (Eq t, Integral a, Num t) => a -> t
fact'' = fact . fromIntegral
This can then be used also as Int -> Integer, which is somewhat sensible.
I'd recommend to just keep the signature (Eq t, Num t) => t -> t though, and only add conversion operations where it's actually needed. Or really, what I'd recommend is to not use fact at all – this is a very expensive function that's hardly ever really useful in practice; most applications that naïvely end up with a factorial really just need something like binomial coefficients, and those can be implemented more efficiently without a factorial.

Why can foldr take a function with three arguments?

I was having a look at some list operations and came across !!:
(!!) :: [a] -> Int -> a
xs !! n
| n < 0 = negIndex
| otherwise = foldr (\x r k -> case k of
0 -> x
_ -> r (k-1)) tooLarge xs n
The function (\x r k -> ...) has type a -> (Int -> a) -> Int -> a, but foldr takes a function that should only accept two arguments:
foldr :: (a -> b -> b) -> b -> [a] -> b
foldr k z = go
where
go [] = z
go (y:ys) = y `k` go ys
Can someone explain to me why foldr accepts a function that takes 3 arguments with the following type a -> (Int -> a) -> Int -> a? Especially since the result should have the same type as the second argument?
-> is right-associative. So a -> b -> c is a -> (b -> c). Therefore, your type
a -> (Int -> a) -> Int -> a
is the same as
a -> (Int -> a) -> (Int -> a)
and we can see that it fits foldr's type quite well.
(more explanation for others ;)
(!!) :: [a] -> Int -> a
xs !! n
| n < 0 = negIndex
| otherwise = foldr (\x r k -> case k of
0 -> x
_ -> r (k-1)) tooLarge xs n
foldr :: (a -> b -> b) -> b -> [a] -> b
-- ^1 ^2
foldr commonly makes an accumulated(?) value. In this case, foldr makes an
accumulated function (b) of the type (Int -> a)! foldr ... tooLarge xs is evaluated to an
accumulated function, and this accumulated function (^2) takes an argument n. ^1 is a tooLarge function. Interestingly, the buildup of this
accumulated function depends on the value of a free variable n (i.e., k).
For example, ['a', 'b', 'c'] !! 2 is evaluated like below:
\x r k = \'a' r 2 -> r (2-1) (r is not known yet, and drives further evaluations.)
\x r k = \'b' r 1 -> r (1-1)
\x r k = \'c' r 0 -> 'c'
['a', 'b', 'c'] !! 3 goes like this:
\x r k = \'a' r 3 -> r (3-1)
\x r k = \'b' r 2 -> r (2-1)
\x r k = \'c' r 1 -> r (1-1) (r turns out to be tooLarge.) = tooLarge (1-1) (ERROR!)
You can check debug traces:
module Main where
import Debug.Trace
tooLarge _ = errorWithoutStackTrace "!!!: index too large"
negIndex = errorWithoutStackTrace "!!!: negative index"
(!!!) :: Show a => [a] -> Int -> a
xs !!! n
| n < 0 = negIndex
| otherwise = foldr (\x r k -> trace ("x: " ++ show x ++ ", k: " ++ show k) $
case k of
0 -> x
_ -> r (k-1)) tooLarge xs n
main = do
print $ ['a', 'b', 'c'] !!! 2
print $ ['a', 'b', 'c'] !!! 3
-- x: 'a', k: 2
-- x: 'b', k: 1
-- x: 'c', k: 0
-- 'c'
-- x: 'a', k: 3
-- x: 'b', k: 2
-- x: 'c', k: 1
-- sample: !!!: index too large
This (!!) implementation is a report version. The report version of the prelude is more efficient than a familiar naive recursive implementation,
due to optimizations of foldr.

Haskell typing priority of operators over functions

I have to derive the type of this function:
func x = map -1 x
And I've already found a way, using a tip to change it to a lambda expression:
func = \x -> (map) - (1 x)
If I express it like that, its fine and I get the same type as the original, but I'm not sure why its grouped like this. Could someone explain it?
For example, why isn't it like this:
func = \x -> (map - 1) x
or something similar.
I know it's a useless function etc. but I can't change the function, I just have to derive its type.
If you write this function in a file, eg:
test.hs has func x = map -1 x
and use :t func in the interpreter, it will reply:
func :: (Num (t -> (a -> b) -> [a] -> [b]),
Num ((a -> b) -> [a] -> [b])) =>
t -> (a -> b) -> [a] -> [b]
I now believe you meant to ask why
func x = map -1 x
has the type (Num (t -> (a -> b) -> [a] -> [b]), Num ((a -> b) -> [a] -> [b])) => t -> (a -> b) -> [a] -> [b], and how you can bracket the expression to make it have that type.
First, you have to recognise that the space is an operator in haskell, and has the highest precedence of all.
Let's use # instead of space, with highest precedence we can:
infixl 9 #
f # x = f x
We can replace and space without an operator with #:
func x = map - 1 # x
because the space between 1 and x was the only one without an operator (- is between map and 1).
Since # has higher precedence than -, we get
func x = map - (1 # x)
or equivalently
func x = map - (1 x)
Another example
func2 x = map (-1) x
> :t func2
func2 :: Num (a -> b) => [a] -> [b]
This translates as
func2' x = map # (-1) # x
but why isn't there a # between the - and the 1? In this case, - in front of a numeric literal like 1 means negate:
> (-1)
-1
> (negate 1)
-1
> (subtract 1)
<interactive>:73:1:
No instance for (Show (a0 -> a0))
arising from a use of `print'
Possible fix: add an instance declaration for (Show (a0 -> a0))
In a stmt of an interactive GHCi command: print it
So this function is trying to map the negative of 1 over a list. For that to work, it would need negative 1 to be a function, which is why it needs a numeric instance for functions (the Num (a->b) => at the start of the type).
but i'm not sure why its grouped like this. Could someone explain it? In example, why its not like that:
func = \x -> (map - 1) x
Precedence. The language definition specifies that the precedence of (prefix) function application is higher than that of any infix operator, so
map -1 x
is parsed as the application of the infix operator (-) to the two operands map and 1 x, like 3 + 4 * 5 is parsed 3 + (4 * 5) due to the higher precedence of (*) compared to that of (+).
Although the interpreter has assigned a type to the expression, it's not a sensible one. Let's see what the function should be
func x = map -1 x
looks like we want to bracket that like this
func x = map (-1) x
in the hope that it subtracts one from each element of a list, but unfortunately, the - is considered to be negation when it's in front of a numeric literal, so we need to bracket it to change it into the subtraction function:
func x = map ((-) 1) x
Now this function subtracts each number in the list from 1:
func [1,2,3]
=[(-) 1 1, (-) 1 2, (-) 1 3]
=[ 1-1, 1-2, 1-3]
=[ 0, -1, -2]
The type is
func :: Num a => [a] -> [a]
If you wanted to subtract one from each element of the list, rather than subtracting each element of the list from 1, you could use func x = map (subtract 1) x. As hammar points out, the subtract function exists exactly for the purpose of allowing this.
Your alternative
func = \x -> (map - 1) x
This can't work because (-) has type Num a => a -> a -> a, whereas map has type (a -> b) -> [a] -> [b]. You can't subtract one from a function, because a function isn't a numeric value.