So i have the result of a function that given a list of ints subtractes an int to all of the numbers in the list and then i want to divide the new list by x in this case 12. If i do the first paragraph of coding it gives me an error but if i do the second one it is possible. How do i do this and why does it give me an error?
let xs = [23,32,1,3]
map (/12) xs
map(/12) [23,32,1,3]
potenciasPor12 xs = map (/12) xs
This is the error i'm getting
<interactive>:176:1:
No instance for (Fractional Int)
arising from a use of ‘potenciasPor12’
In the expression: potenciasPor12 xs
In an equation for ‘it’: it = potenciasPor12 xs
If the monomorphism restriction is set (it is off by default in newer GCHi, but on in compiled code), then xs will default to [Int] rather than the more general type Num a => [a] which would work the the (/) operator.
(In GHCi 8.4.1, at least, it appears to default to Integer instead of Int.)
% ghci
GHCi, version 8.4.1: http://www.haskell.org/ghc/ :? for help
Prelude> let xs = [1,2]
Prelude> :t xs
xs :: Num a => [a]
Prelude> :set -XMonomorphismRestriction
Prelude> let ys = [1,2]
Prelude> :t ys
ys :: [Integer]
Always provide explicit type signatures to be sure:
% ghci -XMonomorphismRestriction
GHCi, version 8.4.1: http://www.haskell.org/ghc/ :? for help
Prelude> let xs = [23,32,1,3] :: Num a => [a]
Prelude> :t xs
xs :: Num a => [a]
Prelude> map (/12) xs
[1.9166666666666667,2.6666666666666665,8.333333333333333e-2,0.25]
Related
I'm trying to define the map function using foldr
I have found the two following solutions, however I'm not quite sure how they are working.
map' :: (a -> b) -> [a] -> [b]
map' f = foldr ((:) . f) []
map'' :: (a -> b) -> [a] -> [b]
map'' f = foldr (\x xs -> f x : xs) []
I'm quite new to Haskell and foldr, so I'm struggling to understand what ((:) . f) in the first solution and what (\x xs -> f x : xs) in the second solution do.
I also don't get how foldr is able handle the empty list case.
It would be much appreciated if I could get a simple step by step explanation of this, in layman's terms.
Both (\x xs -> f x : xs) and (:) . f mean the same thing. They're both functions that take two arguments, apply f to the first argument, and then cons that onto the second argument.
So what does foldr do when given an empty list? It simply returns the starting value, which in these examples is [].
Here is the implementation of foldr from Hackage:
foldr k z = go
where
go [] = z
go (y:ys) = y `k` go ys
so i am struggling a bit with type of functions.
I have a function
prop_merge_check xs ys = length (merge xs ys) == length (sort (xs ++ ys))
how can i assign type for each element of the function?
I tried this way
prop_merge_check :: Eq a => [a] -> [a] -> Bool
and also this way
prop_merge_check xs ys = length (merge (xs::[a]) (ys::[a])) == length (sort ((xs::[a]) ++ (ys::[a])))
But it doesn't seem to work out for me.
Need help pls
Errors are
• Ambiguous type variable ‘a0’ arising from a use of ‘merge’
prevents the constraint ‘(Ord a0)’ from being solved.
Probable fix: use a type annotation to specify what ‘a0’ should be.
These potential instances exist:
instance (Ord a, Ord b) => Ord (Either a b)
-- Defined in ‘Data.Either’
instance Ord Ordering -- Defined in ‘GHC.Classes’
instance Ord Integer
-- Defined in ‘integer-gmp-1.0.2.0:GHC.Integer.Type’
...plus 23 others
...plus 98 instances involving out-of-scope types
(use -fprint-potential-instances to see them all)
• In the first argument of ‘length’, namely
‘(merge (xs :: [a]) (ys :: [a]))’
In the first argument of ‘(==)’, namely
‘length (merge (xs :: [a]) (ys :: [a]))’
In the expression:
length (merge (xs :: [a]) (ys :: [a]))
== length (sort ((xs :: [a]) ++ (ys :: [a])))
And
• Ambiguous type variable ‘a0’ arising from a use of ‘merge’
prevents the constraint ‘(Ord a0)’ from being solved.
Probable fix: use a type annotation to specify what ‘a0’ should be.
These potential instances exist:
instance (Ord a, Ord b) => Ord (Either a b)
-- Defined in ‘Data.Either’
instance Ord Ordering -- Defined in ‘GHC.Classes’
instance Ord Integer
-- Defined in ‘integer-gmp-1.0.2.0:GHC.Integer.Type’
...plus 23 others
...plus 98 instances involving out-of-scope types
(use -fprint-potential-instances to see them all)
• In the first argument of ‘length’, namely
‘(merge (xs :: [a]) (ys :: [a]))’
In the first argument of ‘(==)’, namely
‘length (merge (xs :: [a]) (ys :: [a]))’
In the expression:
length (merge (xs :: [a]) (ys :: [a]))
== length (sort ((xs :: [a]) ++ (ys :: [a])))
As I suspected, the type is not part of the Eq type class, but is part of the Ord type class. Eq specifies how to equal two things and Ord specifies whether something is less than (LT), greater than (GT) or equal to (Eq) something.
Changing your type to: prop_merge_check :: Ord a => [a] -> [a] -> Bool should work.
I have two functions:
prop_merge_check :: Ord a => [a] -> [a] -> Bool
prop_merge_check xs ys = length (merge xs ys) == length (sort (xs ++ ys))
prop_unzip_check :: Ord a => [(a,b)] -> Bool
prop_unzip_check xs = length (unzip xs) >= 0
How can I declare the types of function in a function itself?
I tried this way, but it didn't work out for me.
prop_merge_check xs ys = length (merge (xs::[a]) (ys::[a]))
== length (sort ( (xs::[a]) ++ (ys::[a]) ))
prop_unzip_check xs = length (unzip (xs::[(a,b)])) >= 0
This is a side-effect of Haskell's implicit forall's. Haskell automatically adds 'forall's to all type signatures as necessary, these act as "scoping" rules which limit the names to a particular area. Haskell interprets your signature as:
prop_merge_check :: forall a. Ord a => [a] -> [a] -> Bool
prop_merge_check xs ys =
length (merge (xs::forall a. [a]) (ys:: forall a. [a])) == (length (sort ((xs:: forall a. [a]) ++ (ys:: forall a. [a]))))
That is; it sees every a in every signature as a completely different variable! That's why it can't make the types work properly. This is an annoying and unobvious quirk, but there's a way around it.
If we enable the ScopedTypeVariables and provide an explicit forall in the type signature we tell Haskell that we want the scope of the type variables to span the whole function body:
{-# LANGUAGE ScopedTypeVariables #-}
-- ^ Put that at the top of your module
prop_merge_check :: forall a. Ord a => [a] -> [a] -> Bool
prop_merge_check xs ys =
length (merge (xs::[a]) (ys::[a])) == (length (sort ((xs::[a]) ++ (ys::[a]))))
This version should compile, because now the a in all signatures is considered the same. We can quantify more than one type variable at a time:
prop_unzip_check :: forall a b. Ord a => [(a,b)] -> Bool
prop_unzip_check xs = length (unzip (xs::[(a,b)])) >= 0
Unfortunately there's not currently an easy way to do this sort of thing without adding the explicit forall in the top-level signature, but there are a few proposals for changes to this behaviour. They likely won't be coming any time soon though; so I wouldn't hold your breath.
Good luck! You can look up the docs on ScopedTypeVariables and ExistentialQuantification to learn more about this quirk.
I have written a program that takes a message as a string and returns an anagram by padding the message with X's as needed such that the string length has exactly 4 factors then essentially rearranges the message as if it had been organized in a grid and read down instead of across. For example, inputting, "Haskell" would return the string, "HealslkX". I have written a program that encodes this anagram, but am having trouble writing a program that can reverse the previous program and decode the anagram, particularly with the removeX function that should remove the X padding. Here is what I have:
encode:
import Data.List
factors :: Int -> [Int]
factors n = [x | x <- [1..n], n `mod` x == 0]
split :: Int -> [a] -> [[a]]
split _ [] = []
split n xs =
let (ys, zs) = splitAt n xs
in ys : split n zs
encode :: [Char] -> [Char]
encode (x:xs) = if (length (factors (length xs))) == 4 then concat
(transpose (split ((factors (length xs))!!2) xs))
else encode (xs ++ ['X'])
decode:
import Data.List
factors :: Int -> [Int]
factors n = [x | x <- [1..n], n `mod` x == 0]
split :: Int -> [a] -> [[a]]
split _ [] = []
split n xs =
let (ys, zs) = splitAt n xs
in ys : split n zs
removeX :: [a] -> [a]
removeX xs = if (last xs) == 'X' then ((init xs) && removeX xs)
else xs
decode :: [Char] -> [Char]
decode (x:xs) = removeX (concat (transpose (split ((factors (length xs))!!1) xs)))
Just use removeX (init xs) instead of init xs && removeX xs. Haskell is not procedural (you don't write down a sequence of changes to make) but functional (you write down functions that produce new results from old). Haven't read the rest of the code to see if there are other errors, though.
Also consider removeX = reverse . dropWhile ('X'==) . reverse for better efficiency. Lists are singly-linked, so accesses and modifications at the end are relatively expensive.
I'm learning Haskell. I defined the following function (I know I don't need addToList and I can also do Point-free notation I'm just in the process of playing with language concepts):
map :: (a -> b) -> [a] -> [b]
map f [] = []
map f (x:xs) = addToList (f x) map f xs
where
addToList :: a -> [a] -> [a]
addToList x [] = [x]
addToList x xs = x:xs
This produces a compile error:
with actual type `(a0 -> b0) -> [a0] -> [b0]'
Relevant bindings include
f :: a -> b (bound at PlayGround.hs:12:5)
map :: (a -> b) -> [a] -> [b] (bound at PlayGround.hs:11:1)
Probable cause: `map' is applied to too few arguments
In the second argument of `addToList', namely `map'
In the expression: addToList (f x) map f xs
If I put parantheses around map it works:
map :: (a -> b) -> [a] -> [b]
map f [] = []
map f (x:xs) = addToList (f x) (map f xs)
where
addToList :: a -> [a] -> [a]
addToList x [] = [x]
addToList x xs = x:xs
I understand that function application binds more tightly than operators (as discussed in Haskell - too few arguments), however, I don't understand how the compiler would parse the above differently without the parantheses.
The simple way to see that something is wrong is to note that the expression:
addToList (f x) map f xs
is applying 4 arguments to addToList whereas:
addToList (f x) (map f xs)
is applying two arguments to addToList (which is what addToList "expects").
Update
Note that even though map takes two arguments, this expression:
addToList a map c d
is parsed as:
(((addToList a) map) c) d
So here's a possible explanation of what GHC is thinking...
addToList (f x) has type [a] -> [a] - i.e. it is a function which takes a list.
map has type (c -> d) -> [c] -> [d]. It is not a list, but with additional arguments it could produce a list.
So when GHC sees addTolist (f x) map and can't type check it, it sees that if map only had a few more arguments, like this:
addToList (f x) (map ...)
at least the second argument to addToList would be a list - so perhaps that's the problem.
Parsing is a distinct step that is completed before type checking occurs. The expression
addToList (f x) map f xs
has as much meaning to the parser as s1 (s2 s3) s4 s2 s5 has to you. It doesn't know anything about what the names mean. It takes the lexical structure of the string and turns it into a parse tree like
*5
/ \
/ xs
*4
/ \
/ f
*3
/ \
/ map
*2
/ \
addToList *1
/ \
f x
Once the parse tree is complete, then each node is tagged with its type, and type checking can occur. Since function application is denoted simply by juxtaposition, the type checker knows that the left child of a node is a function, the right child is the argument, and the root is the result.
The type checker can proceed roughly as follows, doing an pre-order traversal of the tree. (I'll alter the type signatures slightly to distinguish unrelated type variables until they are unified.)
addToList :: a -> [a] -> [a], so it takes an argument of type a and returns a function of type [a] -> [a]. The value of a is not yet known.
f :: b -> c, so it takes an argument of type b and returns a value of type c. The values of b and c are not yet known.
x has type d. The value of d is not yet known.
Letting b ~ d, f can be applied to x, so *1 :: c
Letting a ~ c, addToList is applied to *1, so *2 :: [a] -> [a]
Uh oh. *2 expects an argument of type [a], but it is being applied to map :: (e -> f) -> [e] -> [f]. The type checker does not know how to unify a list type and a function type, which produces the error you see.