No instance for (Num a) arising from a use of `sum' - Instance Num - haskell

this function works fine:
fromDigits :: [Int] -> Int
fromDigits n = sum (zipWith (\x y -> x*y) (n) (f n 0))
where
f :: [Int] -> Int -> [Int]
f n x = if (x==length n) then []
else (10^x):f n (x+1)
But if i want to change the type signature from the function, it does not work:
fromDigits :: (Num a) => [a] -> a
fromDigits n = sum (zipWith (\x y -> x*y) (n) (f n 0))
where
f :: (Num a) => [a] -> a -> [a]
f n x = if (x==length n) then []
else (10^x):f n (x+1)
Shouldn't this work too?

Almost, but not quite. The basic problem is that length has type [a]->Int. This will work:
fromDigits :: Num a => [a] -> a
fromDigits n = sum (zipWith (\x y -> x*y) (n) (f n 0))
where
f :: Num b => [b] -> Int -> [b]
f n x = if (x==length n) then []
else (10^x):f n (x+1)
As Oleg Grenrus points out, one should always be careful to check if Int might overflow. It is in fact possible for this to happen if Int is 30, 31, or 32 bits, although it is relatively unlikely. However, if that is a concern, there is a way around it, using another function:
lengthIsExactly :: Integral n => n -> [a] -> Bool
lengthIsExactly = -- I'll let you figure this one out.
-- Remember: you can't use `length` here,
-- and `genericLength` is horribly inefficient,
-- and there's a completely different way.
You can make it easier to see how the types of fromDigits and f match up using a GHC extension. Enable the extension by adding
{-# LANGUAGE ScopedTypeVariables #-}
to the very top of your source file. Then you can write
fromDigits :: forall a . Num a => [a] -> a
fromDigits n = sum (zipWith (\x y -> x*y) (n) (f n 0))
where
f :: [a] -> Int -> [a]
f n x = if (x==length n) then []
else (10^x):f n (x+1)
This way, it's clear that the list arguments all have the same type.

The problem is that you are using other functions that require even more of type a than just Num a
(^) requires "Integral a"
This works
fromDigits' :: (Num a, Integral a)=>[a] -> a
fromDigits' n = sum (zipWith (\x y -> x*y) (n) (f n 0))
where
f :: (Num a, Integral a)=>[a] -> a -> [a]
f n x = if (x==fromIntegral (length n)) then []
else (10^x):f n (x+1)

Related

Haskell: Finding the type of an expression involving map

I am trying to find the type of the following Haskell expression:
map (\x -> x + 1)
Since the map function is partially applied, it will return another function.
In GHCI, the type of the function that is returned is:
let res = map (\x -> x + 1)
:t res
map (\x -> x + 1) :: Num b => [b] -> [b]
Would the type of the above expression be the type of the function that is returned? Any insights are appreciated.
Yes, that is the type of the function which is returned.
But how does GHC figure this out? Well, let's look at the type of just plain map:
map :: (a -> b) -> [a] -> [b]
And now let's look at the type of \x -> x + 1:
(\x -> x + 1) :: Num n => n -> n
(In case you don't know yet, this means that it converts n to n, where n can be any type which is an instance of Num i.e. n is any number type.)
So matching up the types, we get:
map :: (a -> b) -> [a] -> [b]
(\x -> x + 1) :: Num n => n -> n
So:
map (\x -> x + 1) :: Num n => [n] -> [n]
Which is the same as what GHCi reports.

How would you declare the types of these functions in Haskell?

So I'm learning about Haskell at the moment, and I came across this question:
The type of a function f is supposed to be a->[a]->a. The
following definitions of f are incorrect because their types are all
different from a->[a]->a:
i. f x xs = xs
ii. f x xs = x+1
iii. f x xs = x ++ xs
iv. f x (y:ys) = y
My answers as I see it are:
i) f :: a -> a -> a
This is because x or xs can be of any value and is not a list as it does not contain the ':' operator.
ii) f :: Int -> a -> Int
This is because the + operator is used on x, meaning x is of type Int.
iii) f :: Eq a => a -> a -> a
The ++ operators are used, therefore in order to concatenate they must be of the same type..?
iv) f :: a -> [a] -> a
f returns an element from the list.
The last one is definitely wrong, because it can't be of type a -> [a] -> a. Are there any others I did wrong, and why? I'm hoping I can fully understand types and how to find out the types of functions.
i) f :: a -> a -> a
f x xs = xs
This is because x or xs can be of any value and is not a list as it does not contain the ':' operator.
True, but it also does not have to be of the same type!
So, it's actually f :: a -> b -> b.
ii) f :: Int -> a -> Int
f x xs = x+1
This is because the + operator is used on x, meaning x is of type Int.
Correct. (Actually, in Haskell we get Num b => b -> a -> b which generalized the Int to any numeric type, but it's not that important.)
iii) f :: Eq a => a -> a -> a
f x xs = x ++ xs
The ++ operators are used, therefore in order to concatenate they must be of the same type..?
True, but they must be lists. Also, Eq is only needed if you use == or something which compares values.
Here, f :: [a] -> [a] -> [a].
iv) f :: a -> [a] -> a
f x (y:ys) = y
f returns an element from the list.
The type of x does not have to be the same. We get f :: b -> [a] -> a.
i. f x xs = xs
(...)
i) f :: a -> a -> a
Although this can be a type signature, you make it too restrictive. The function takes two parameters x and xs. Initially we can reason that x and xs can have different types, so we say that x :: a, and xs :: b. Since the function returns xs, the return type is b as well, so the type is:
f :: a -> b -> b
f x xs = xs
ii. f x xs = x+1
(...)
ii) f :: Int -> a -> Int
Again you make the function too restrictive. Let us again assume that x :: a and xs :: b have different types. We see that we return x + 1 (or in more canonical form (+) x 1. Since (+) has signature (+) :: Num c => c -> c -> c (we here use c since a is already used), and 1 has signature 1 :: Num d => d, we thus see that we call (+) with x and 1, as a result we know that a ~ c (a and c are the same type), and c ~ d, so as a result we obtain the signature:
f :: Num c => c -> b -> c
f x xs = x+1
iii. f x xs = x ++ xs
(...)
iii) f :: Eq a => a -> a -> a
This is wrong: we here see that f has two parameters, x :: a and xs :: b. We see that we return (++) x xs. Since (++) has signature (++) :: [c] -> [c] -> [c], we thus know that a ~ [c] and b ~ [c], so the type is:
f :: [c] -> [c] -> [c]
f x xs = x ++ xs
iv. f x (y:ys) = y
(...)
iv) f :: a -> [a] -> a
This is again too restrictive. Here we see again two parameters: x and (y:ys). We first generate a type a for x :: a, and (y:ys) :: b, since the pattern of the second parameter is (y:ys), this is a list constructor with as parameters (:) :: c -> [c] -> [c]. As a result we can derive that y :: c, and ys :: [c], furthermore the pattern (y:ys) has type [c]. Since the function returns y, we know that the return type is c, so:
f :: a -> [c] -> c
f x (y:ys) = y
Note: you can let Haskell derive the type of the function itself. In GHCi you can use the :t command to query the type of an expression. For example:
Prelude> f x (y:ys) = y
Prelude> :t f
f :: t1 -> [t] -> t

Can mapEvery be implemented with foldr

For a function that maps a function to every nth element in a list:
mapEvery :: Int -> (a -> a) -> [a] -> [a]
mapEvery n f = zipWith ($) (drop 1 . cycle . take n $ f : repeat id)
Is it possible to implement this with foldr like ordinary map?
EDIT: In the title, changed 'folder' to 'foldr'. Autocorrect...
Here's one solution
mapEvery :: Int -> (a -> a) -> [a] -> [a]
mapEvery n f as = foldr go (const []) as 1 where
go a as m
| m == n = f a : as 1
| otherwise = a : as (m+1)
This uses the "foldl as foldr" trick to pass state from the left to the right along the list as you fold. Essentially, if we read the type of foldr as (a -> r -> r) -> r -> [a] -> r then we instantiate r as Int -> [a] where the passed integer is the current number of elements we've passed without calling the function.
Yes, it can:
mapEvery :: Int -> (a -> a) -> [a] -> [a]
mapEvery n f xs
= foldr (\y ys -> g y : ys) []
$ zip [1..] xs
where
g (i, y) = if i `mod` n == 0 then f y else y
And since it's possible to implement zip in terms of foldr, you could get even more fold-y if you really wanted. This even works on infinite lists:
> take 20 $ mapEvery 5 (+1) $ repeat 1
[1,1,1,1,2,1,1,1,1,2,1,1,1,1,2,1,1,1,1,2]
This is what it looks like with even more foldr and inlining g:
mapEvery :: Int -> (a -> a) -> [a] -> [a]
mapEvery _ _ [] = []
mapEvery n f xs
= foldr (\(i, y) ys -> (if i `mod` n == 0 then f y else y) : ys) []
$ foldr step (const []) [1..] xs
where
step _ _ [] = []
step x zipsfn (y:ys) = (x, y) : zipsfn ys
Now, would I recommend writing it this way? Absolutely not. This is about as obfuscated as you can get while still writing "readable" code. But it does demonstrate that this is possible to use the very powerful foldr to implement relatively complex functions.

Converting Function To Maybe Type

I am trying to convert a function of maximum utilizing a foldr function to one that also incorporates the maybe type. It is originally:
maximum' :: (Ord a) => [a] -> a
maximum' = foldr1 (\x acc -> if x > acc then x else acc)
It works perfectly with sets, but not with the empty set. I want to convert it to use maybe types instead.
My thought process was:
mymax :: (Ord a) => [Maybe a] -> Maybe a
mymax = foldr (\(Just x) (Just b) -> if ((Just x) > (Just b)) then (Just x) else (Just b)) Nothing
It compiles with no errors and works when I give it the empty set. However, when I give it a set with numbers in it, it no longer works! Can someone point me in the right direction on how I can get the functionality of it also getting the maximum from a list of maybes?
I really want to use the foldr function in my solution....
I've now tried:
mymax :: (Ord a) => [a] -> Maybe a
mymax = foldr (\x b -> if x > b then (Just x) else (Just b)) Nothing
But it will not compile:
Couldn't match expected type `Maybe b -> Maybe a'
with actual type `Maybe a0'
In the return type of a call of `Just'
Probable cause: `Just' is applied to too many arguments
In the expression: (Just x)
In the expression: if x > b then (Just x) else (Just b)
Failed, modules loaded: none.
If you want to do it in a single foldr, we can exploit the fact that Ord a => Ord (Maybe a), that is, any ordering on a can be extended to an ordering on Maybe a.
We also have Just x > Nothing, for all x :: Ord a => a.
mymax :: (Ord a) => [a] -> Maybe a
mymax = foldr (\x b -> let x' = Just x in if x' > b then x' else b) Nothing
-- equivalently
mymax = foldr (\x b -> let x' = Just x in max x' b) Nothing
mymax = foldr (\x' b -> max x' b) Nothing . map (\x -> Just x)
mymax = foldr max Nothing . map Just
If we want to do minimum, we'll have to do it a bit differently, since Nothing is the lower bound for the type Ord a => Maybe a, which means that foldr min Nothing . map Just == const Nothing, which isn't useful.
mymin :: (Ord a) => [a] -> Maybe a
mymin = foldr (\x b -> case b of
Nothing -> Just x
Just y -> Just (min x y)
) Nothing
-- which is equivalent to
mymin = foldr (\x b -> Just $ case b of
Nothing -> x
Just y -> min x y
) Nothing
mymin = foldr (\x b -> Just $ maybe x (min x) b) Nothing
mymin = foldr (\x -> Just . maybe x (min x)) Nothing
Honestly, though, I think pattern matching makes solutions a lot clearer
mymax [] = Nothing
mymax (a:as) = Just $ foldr max a as
mymin [] = Nothing
mymin (a:as) = Just $ foldr min a as
I think you actually want mymax to have type (Ord a) => [a] -> Maybe a. Here's a potential implementation that uses pattern matching and your original maximum' function:
mymax :: (Ord a) => [a] -> Maybe a
mymax [] = Nothing
mymax xs = Just (maximum' xs)
Also, Learn You A Haskell is a great resource if you haven't already come across it!

relation between monadic filter and fold

Many higher-order functions can be defined in term of the fold function. For example, here is the relation between filter and foldl in Haskell.
myFilter p [] = []
myFilter p l = foldl (\y x -> if (p x) then (x:y) else y) [] (reverse l)
Is there a similar relation between their monadic versions filterM and foldM ? How can I write filterM in term of foldM ?
I tried hard to find a monadic equivalent to \y x -> if (p x) then (x:y) else y to plug into foldM without success.
Like in D.M.'s answer, only without the reverse. Let the types guide you:
import Control.Monad
{-
foldM :: (Monad m) => (b -> a -> m b) -> b -> [a] -> m b
filterM :: (Monad m) => (a -> m Bool) -> [a] -> m [a]
-}
filtM :: (Monad m) => (a -> m Bool) -> [a] -> m [a]
filtM p xs = foldM f id xs >>= (return . ($ []))
where
f acc x = do t <- p x
if t then return (acc.(x:)) else return acc
Not sure that it has any sense (since it has that strange reverse), but at least it type checked well:
myFilterM :: Monad m => (a -> m Bool) -> [a] -> m [a]
myFilterM p l = foldM f [] (reverse l)
where
f y x = do
p1 <- p x
return $ if p1 then (x:y) else y

Resources