Sort a list into tuples - function

I’m new to Haskell and am trying to sort a list of tuples using their first element, using the sort function. So if I had ["a", "b", "a", "c", "c"] I would get something like [(1,"b"), (2,"a"), (2,"c")] (in alphabetical order in the event of the same number).
How would I go about doing this? I am totally lost at the moment… I am still trying to get into the ‘Haskell way of thinking’.

import Data.List (sort, group)
import Control.Arrow ((&&&))
answer :: Eq a => [a] -> [(Int, a)]
answer = sort . map (length &&& head) . group . sort
But as you're a beginner, it's perhaps a bit much to tell you about &&&, so I'll rewrite it like this:
import Data.List (sort, group)
answer :: Eq a => [a] -> [(Int, a)]
answer = sort . map f . group . sort
where f xs # (x:_) = (length xs, x)
You'll note I'm calling sort twice. This is intentional.
The final sort (the one on the left) sorts the output list of tuples, and it just so happens that it sorts in ascending order of the first element of the tuple, breaking ties by sorting on the second element of the tuple.
The initial sort (the one on the right) sorts the input list, because of what group does: it groups adjacent equal elements into a sublist. (Incidentally, these sublists are guaranteed never to be empty --- otherwise it wouldn't be safe to use head or ignore the empty list option in the pattern match.)
The map f then turns these lists (e.g. ["a", "a"]) into what we're interested in: the number of times these elements occur, and a single representative of these elements (e.g. (2, "a")).
The idiom here is that we're using a pipeline: our input goes into a function, the output of that function goes into another function, and so on until the function at the end of the pipeline produces output that we present as our own output. Note that this only works because each function takes only a single argument (map takes two arguments, f is the first of those arguments, so map f takes one argument).
As a consequence of this, answer is a function even though its argument doesn't explicitly appear. This is point-free style.
In non point-free style, it would look like
answer xs = sort . map f . group . sort $ xs
where f xs # (x:_) = (length xs, x)
or
answer xs = sort $ map f $ group $ sort xs
where f xs # (x:_) = (length xs, x)
or
answer xs = sort (map f (group (sort xs)))
where f xs # (x:_) = (length xs, x)
It is a good idea to use point-free style when it makes your code clearer.
If you like, you can use the <<< operator (from Control.Arrow again, sorry) to make the dataflow direction superficially more explicit:
import Data.List (sort, group)
import Control.Arrow ((<<<))
answer :: Eq a => [a] -> [(Int, a)]
answer = sort <<< map f <<< group <<< sort
where f xs # (x:_) = (length xs, x)
Some people think that this is the wrong way round and want the functions that "happen" first to be on the left. These people can use >>> (also from Control.Arrow), which is exactly the same as <<< except its arguments are flipped round:
import Data.List (sort, group)
import Control.Arrow ((>>>))
answer :: Eq a => [a] -> [(Int, a)]
answer = sort >>> group >>> map f >>> sort
where f xs # (x:_) = (length xs, x)

Related

error message by list comprehension with floored float numbers and in lambda functions

I'm learning Haskell and have some problems with list comprehension.
If I define a function to get a list of the divisors of a given number, I get an error.
check n = [x | x <- [1..(floor (n/2))], mod n x == 0]
I don't get why it's causing an error. If I want to generate a list from 1 to n/2 I can do it with [1..(floor (n/2))], but not if I do it in the list comprehension.
I tried another way but I get also an error (in this code I want to get all so called "perfect numbers")
f n = [1..(floor (n/2))]
main = print $ filter (\t -> foldr (+) 0 (f t) == t) [2..100]
Usually it is better to start writing a signature. While signatures are often not required, it makes it easier to debug a single function.
The signature of your check function is:
check :: (RealFrac a, Integral a) => a -> [a]
The type of input (and output) a thus needs to be both a RealFrac and an Integral. While technically speaking we can make such type, it does not make much sense.
The reason this happens is because of the use of mod :: Integral a => a -> a -> a this requires x and n to be both of the same type, and a should be a member of the Integral typeclass.
Another problem is the use of n/2, since (/) :: Fractional a => a -> a -> a requires that n and 2 have the same type as n / 2, and n should also be of a type that is a member of Fractional. To make matters even worse, we use floor :: (RealFrac a, Integral b) => a -> b which enforces that n (and thus x as well) have a type that is a member of the RealFrac typeclass.
We can prevent the Fractional and RealFrac type constaints by making use of div :: Integral a => a -> a -> a instead. Since mod already required n to have a type that is a member of the Integral typeclass, this thus will not restrict the types further:
check n = [x | x <- [1 .. div n 2], mod n x == 0]
This for example prints:
Prelude> print (check 5)
[1]
Prelude> print (check 17)
[1]
Prelude> print (check 18)
[1,2,3,6,9]

Haskell Programming simple function recurrsion

for this program an element and a list is taken in and a new list is returned. if there are any occurrences of the element in the list, they should be deleted in the list that is returned.
allOcrDelete :: Eq a => a -> [a] -> [a]
allOcrDelete del = if head [a] == number then allOcrDelete(tail [a])
else del ++ [head [a]] ++ allOcrDelete(tail [a])
this is what i have so far. i'm not sure how to take an element and a list as parameters and how to take the head or tail and compare the head to the element to be deleted
As jamshidh mentioned, you can use filter and write:
allOcrDelete del = filter (/= del)
(allOcrDelete is a special case of filter)
A naive implementation could be:
module Main where
allOcrDelete :: Eq a => a -> [a] -> [a]
allOcrDelete _ [] = []
allOcrDelete del (x:xs)
| del == x = allOcrDelete del xs
| otherwise = x:allOcrDelete del xs
main = do
print $ allOcrDelete 2 [1,2,5,3,2,4,5,2]
Note:
you don't need to use the head and tail functions in this case because pattern matching the list against (x:xs) will already split the list into the head x and the tail xs (this is a common pattern in Haskell)
First let me say, don't use head and tail, ever. ...Well, at least not until you've gathered so much experience that you can recognise the few cases when it actually makes something more concise. Usually pattern matching (or folding etc.) is not only much safer but also far more readable & intuitive.
So in your case, you're trying to get head [a]. What is [a]? You evidently mean, “the argument of the function which has type [a], but that's not possible to write in Haskell code. (What if there was yet another element of the same type?) To use an argument, you have to _bring it in scope, with some arbitrary name (only, names can't contain brackets), e.g.
delete' del xs = if head xs == number then delete'(tail xs)
else del ++ [head xs] ++ delete'(tail xs)
would work. (Sort of. number also doesn't make sense there: you probably want to compare with del, instead of inserting that.)
However, since the only thing you do with xs is call those evil head and tail functions, you should rather write it this way:
delete' del (x:xs) = if x == number then delete' xs
else del ++ [x] ++ delete' xs

Ambiguous type variable in polyvariadic curry definition

So, I'm trying to implement a polyvariadic ZipWithN as described here. Unfortunately, Paczesiowa's code seems to have been compiled with outdated versions of both ghc and HList, so in the process of trying to understand how it works, I've also been porting it up to the most recent versions of both of those (ghc-7.8.3 and HList-0.3.4.1 at this time). It's been fun.
Anyways, I've run into a bug that google isn't helping me fix for once, in the definition of an intermediary function curryN'. In concept, curryN' is simple: it takes a type-level natural number N (or, strictly speaking, a value of that type), and a function f whose first argument is an HList of length N, and returns an N-ary function that takes makes an HList out of its first N arguments, and returns f applied to that HList. It's curry, but polyvariadic.
It uses three helper functions/classes:
The first is ResultType/resultType, as I've defined here. resultType takes a single function as an argument, and returns the type of that function after applying it to as many arguments as it will take. (Strictly speaking, again, it returns an undefined value of that type).
For example:
ghci> :t resultType (++)
resultType (++) :: [a]
ghci> :t resultType negate
resultType negate :: (ResultType a result, Num a) => result
(The latter case because if a happens to be a function of type x -> y, resultType would have to return y. So it's not perfect applied to polymorphic functions.)
The second two are Eat/eat and MComp/mcomp, defined together (along with curryN') in a single file (along with the broken curryN') like this.
eat's first argument is a value whose type is a natural number N, and returns a function that takes N arguments and returns them combined into an HList:
ghci> :t eat (hSucc (hSucc hZero))
eat (hSucc (hSucc hZero)) :: x -> x1 -> HList '[x, x1]
ghci> eat (hSucc (hSucc hZero)) 5 "2"
H[5, "2"]
As far as I can tell it works perfectly. mcomp is a polyvariadic compose function. It takes two functions, f and g, where f takes some number of arguments N. It returns a function that takes N arguments, applies f to all of them, and then applies g to f. (The function order parallels (>>>) more than (.))
ghci> :t (,,) `mcomp` show
(,,) `mcomp` show :: (Show c, Show b, Show a) => a -> b -> c -> [Char]
ghci> ((,,) `mcomp` show) 4 "str" 'c'
"(4,\"str\",'c')"
Like resultType, it "breaks" on functions whose return types are type variables, but since I only plan on using it on eat (whose ultimate return type is just an HList), it should work (Paczesiowa seems to think so, at least). And it does, if the first argument to eat is fixed:
\f -> eat (hSucc (hSucc hZero)) `mcomp` f
works fine.
curryN' however, is defined like this:
curryN' n f = eat n `mcomp` f
Trying to load this into ghci, however, gets this error:
Part3.hs:51:1:
Could not deduce (Eat n '[] f0)
arising from the ambiguity check for ‘curryN'’
from the context (Eat n '[] f,
MComp f cp d result,
ResultType f cp)
bound by the inferred type for ‘curryN'’:
(Eat n '[] f, MComp f cp d result, ResultType f cp) =>
Proxy n -> (cp -> d) -> result
at Part3.hs:51:1-29
The type variable ‘f0’ is ambiguous
When checking that ‘curryN'’
has the inferred type ‘forall f cp d result (n :: HNat).
(Eat n '[] f, MComp f cp d result, ResultType f cp) =>
Proxy n -> (cp -> d) -> result’
Probable cause: the inferred type is ambiguous
Failed, modules loaded: Part1.
So clearly eat and mcomp don't play as nicely together as I would hope. Incidentally, this is significantly different from the kind of error that mcomp (+) (+1) gives, which complains about overlapping instances for MComp.
Anyway, trying to find information on this error didn't lead me to anything useful - with the biggest obstacle for my own debugging being that I have no idea what the type variable f0 even is, as it doesn't appear in any of the type signatures or contexts ghci infers.
My best guess is that mcomp is having trouble recursing through eat's polymorphic return type (even though what that is is fixed by a type-level natural number). But if that is the case, I don't know how I'd go about fixing it.
Additionally (and bizarrely to me), if I try to combine Part1.hs and Part2.hs into a single file, I still get an error...but a different one
Part3alt.hs:59:12:
Overlapping instances for ResultType f0 cp
arising from the ambiguity check for ‘curryN'’
Matching givens (or their superclasses):
(ResultType f cp)
bound by the type signature for
curryN' :: (MComp f cp d result, Eat n '[] f, ResultType f cp) =>
Proxy n -> (cp -> d) -> result
at Part3alt.hs:(59,12)-(60,41)
Matching instances:
instance result ~ x => ResultType x result
-- Defined at Part3alt.hs:19:10
instance ResultType y result => ResultType (x -> y) result
-- Defined at Part3alt.hs:22:10
(The choice depends on the instantiation of ‘cp, f0’)
In the ambiguity check for:
forall (n :: HNat) cp d result f.
(MComp f cp d result, Eat n '[] f, ResultType f cp) =>
Proxy n -> (cp -> d) -> result
To defer the ambiguity check to use sites, enable AllowAmbiguousTypes
In the type signature for ‘curryN'’:
curryN' :: (MComp f cp d result, Eat n [] f, ResultType f cp) =>
Proxy n -> (cp -> d) -> result
Failed, modules loaded: none.
Again with the mysterious f0 type variable. I'll admit that I'm a little bit over my head here with all this typehackery, so if anyone could help me figure out what exactly the problem here is, and, more importantly, how I can fix it (if it is, hopefully, possible), I'd be incredibly grateful.
Final note: the reasons that the two files here are called Part1 and Part3 is that Part2 contains some auxiliary functions used in zipWithN, but not curryN'. For the most part they work fine, but there are a couple of oddities that I might ask about later.

Rewriting an uncurried function haskell

I've been learning about uncurrying and applying $ in functions in haskell but I'm still having issues converting an uncurried function to something less mysterious.
The function I'm given is
apple = map $ uncurry $ flip ($)
and I realize that this takes a list of tuples and applies to corresponding function in the tuple to the variable inside. So I'm trying to rewrite it as
apple ls = foldr function _ ls
where function (a,b) c = (uncurry b) (a,c)
I get the error for _ as a parse error and I have no idea which starting point to use. I need to make this polymorphic and I'm realizing that this most likely will not be the way to make it less mysterious. Any ideas? They'd be greatly appreciated
Apple has the type
apple :: [(a, a->b)] -> [b]
We could rewrite it as
apple ls = map (\(a, f) -> f a) ls
So writing this with foldr is very doable,
apple ls = foldr (\(a, f) rest -> f a : rest) [] ls
Or, we can rewrite this to pointfree
apple = foldr ( (:) . (uncurry . flip $ ($)) ) []
The reason for the parse error is that _ is the special syntax for "variables I don't care about". This let's you write things like
foo _ _ _ _ a = a
And not get an error about repeated variables. Basically we just filled in _ with the starting empty list and fixed function so that it appends to c rather than trying to apply it to a.
If I wanted to write this in the clearest way possible, then the original
apple = map . uncurry . flip $ ($)
Is quite nice.
The key for understanding is removing complexity.
Thus I would suggest you deal with a single tuple first. Write the following function:
tapp :: (a, a ->b) -> b
in terms of ($) and flip and uncurry.
(To make it even easier, you could first do it for a tuple (a -> b, a) first).
Next, make clear to yourself how map works: If you have a function f :: (a -> b), then map f will be a function [a] -> [b]. Hence map tapp does what you want.
You can now replace tapp in map (tapp) by it's definition (this are the benefits of referential transparency).
And this should take you back to your original expression. More or less so, because, for example:
f $ g h
can be written
f (g h)
or
(f . g) h

Function application: Why is $ used here?

A while ago, I asked a question about $, and got useful answers -- in fact, I thought I understood how to use it.
It seems I was wrong :(
This example shows up in a tutorial:
instance Monad [] where
xs >>= f = concat . map f $ xs
I can't for the life of me see why $ was used there; ghci isn't helping me either, as even tests I do there seem to show equivalence with the version that would simply omit the $. Can someone clarify this for me?
The $ is used here because it has lower precedence than normal function application.
Another way to write this code is like so:
instance Monad [] where
xs >>= f = (concat . map f) xs
The idea here is to first construct a function (concat . map f) and then apply it to its argument (xs). As shown, this can also be done by simply putting parenthesis around the first part.
Note that omitting the $ in the original definition is not possible, it will result in a type error. This is because the function composition operator (the .) has a lower precedence than normal function application effectively turning the expression into:
instance Monad [] where
xs >>= f = concat . (map f xs)
Which doesn't make sense, because the second argument to the function composition operator isn't a function at all. Although the following definition does make sense:
instance Monad [] where
xs >>= f = concat (map f xs)
Incidentally, this is also the definition I would prefer, because it seems to me to be a lot clearer.
I'd like to explain why IMHO this is not the used style there:
instance Monad [] where
xs >>= f = concat (map f xs)
concat . map f is an example of so-called pointfree-style writing; where pointfree means "without the point of application". Remember that in maths, in the expression y=f(x), we say that f is applied on the point x. In most cases, you can actually do a final step, replacing:
f x = something $ x
with
f = something
like f = concat . map f, and this is actually pointfree style.
Which is clearer is arguable, but the pointfree style gives a different point of view which is also useful, so sometimes is used even when not exactly needed.
EDIT: I have replaced pointless with pointfree and fixed some examples, after the comment by Alasdair, whom I should thank.
The reason $ is used here is doe to the type signature of (.):
(.) :: (b -> c) -> (a -> c) -> a -> c
Here we have
map f :: [a] -> [[b]]
and
concat :: [[b]] -> [b]
So we end up with
concat . map f :: [a] -> [b]
and the type of (.) could be written as
(.) :: ([[b]] -> [b]) -> ([a] -> [[b]]) -> [a] -> [b]
If we were to use concat . map f xs, we'd see that
map f xs :: [[b]]
And so cannot be used with (.). (the type would have to be (.) :: (a -> b) -> a -> b