Haskell Map function implementation issues - haskell

I just began to learn Haskell and am having trouble with adjusting to the language, for example on the implementation of map more specifically when trying to do similar operations as in the example bellow;
rotate :: Dimensions -> imgBlock -> [(imgBlock,Int)]
rotate d ((p, pix), s, t)
= zip [((p, f pix), s, t) | f <- transformate (fst d)] [0..7]
makeAllRotations :: Dimensions -> [imgBlock] -> [(imgBlock,Int)]
makeAllRotations d ib = map concat (rotate d ib) //Error points Here
Where
type imgBlock = (Block, Int, Int)
type Block = (Pnt, Pxl)
type Dimensions = (Int, Int)
And this is one of the errors i get
asdf.hs:73:30:
Couldn't match expected type `(imgBlock, Int)'
with actual type `[a0]'
Expected type: [[a0]] -> (imgBlock, Int)
Actual type: [[a0]] -> [a0]
In the first argument of `map', namely `concat'
In the expression: map concat (rotate d ib)
I find myself quite frustrated trying to adjust to this new programming 'paradigm' where most of the things I managed to do are through trial and error. I am obviously not understanding map correctly, although i have read the documentation on this website, but all the examples are shown in console like map (2+) [1,2,3] not so much when using them in functions.
Could I get some pointers on where am i going wrong on my map implementation. Thks

The best way to find the problem is to look at the types:
rotate :: Dimensions -> ImgBlock -> [(ImgBlock,Int)]
makeAllRotations :: Dimensions -> [ImgBlock] -> [(ImgBlock,Int)]
map :: (a -> b) -> [a] -> [b]
concat :: [[a]] -> [a]
The map function is trying to call concat on each of the (ImgBlock,Int) pairs in the list returned by rotate. But concat expects to get a nested list as its argument. But the big thing that helped me figure out how to fix it was looking at rotate d ib. The second argument to rotate is ImgBlock, but in that context ib :: [ImgBlock]. You can't pass in a list when a single item is expected. But that's what the map function is for. It allows you to take a function that accepts a single item ('a' in the type signature above) and use that function when you have [a]. I suspect what you want is something like this:
makeAllRotations d ib = concat $ map (rotate d) ib
Because rotate returns a list, map (rotate d) ib returns a list of lists, which fits perfectly as the first argument to the concat function.

Related

Re-write 'map intToDigit' with a fold...

So this one seems like it should be super-simple... but I'm not sure where to stick the 'fold' in (obviously you could fold either way)...
It says "write a function ( intToString :: [Int] -> [Char] ) using a fold, that mimics this map:
map intToDigit [5,2,8,3,4] == "52834"
And then says, "For the conversion, use intToDigit :: Int -> Char from Data.Char."
I'm not entirely sure I get the point... but yet it doesn't seem like it should be that hard -- you're just reading in the list (folding it in, I get how folds work in general) from either the left or right and doing the conversion... but I'm not sure how to set it up.
It is not difficult, think about the definition foldr (or foldl) of List:
foldr::(a -> b -> b) -> b -> [a] -> b
Here (a->b->b) is the step function which will be applied on each element of list [a], b is your target.
Now, you have a list of Int ([Int]), and need to convert to [Char] (or String).
Relpace [a] by [5,2,8,3,4], b by []::[Char] (your target) and (a->b->b) by step function :
foldr step ([]::[Char]) [5,2,8,3,4]
We have known that step function has type (a->b->b), specifically, (Int->[Char]->[Char]), the job need to do just convert Int to [Char], as mentioned in question: intToDigit can be helped to convert Int to Char and (:) operator can append element at the head of List so:
step x s = intToDigit x : s
where s is [Char] (or String), put them all:
foldr (\x s->intToDigit x : s) [] [5,2,8,3,4]

Access return value

Let's say I have this function:
functionName :: notimportant => a -> ([a])
I would like to recursively call this function and at each call to modify/update the return (the 2 elements from the tuple). The problem is that I do not know how to pattern match the tuple in order to add at each function's call elements in the list(the first parameter of the returned tuple).
I haven't understood your question. If it becomes more coherent, so may this answer.
The canonical code that applies a function like yours recursively is the following:
data Tree a = Node a [a]
unfold :: (a -> [a]) -> a -> Tree a
unfold f x = Node x $ map (unfold f) $ f x
You talk of tuples. I see no tuple in your type signature.

Converting types in Haskell

I'm working on a conversion problem for homework, and am a complete Haskell newbie, so bear with me. On one of them, it asks us to attempt to get the type of a function to be:
fc :: (Bool, [Char]) -> Int -> Integer -> [Bool]
Without worrying about what the actual function does or anything. These functions will not be run, it is just a test to see if we can convert types correctly. So far the furthest I can get is this:
fc :: (Bool, [Char]) -> Int
fc (x, y) = ord (head y)
Where I am turning it into an Int. When I try to turn it into an Integer using the toInteger function, it gives me:
Couldn't match expected type `Int -> Integer'
with actual type `Integer'
In the return type of a call of `toInteger'
Probable cause: `toInteger' is applied to too many arguments
In the expression: toInteger (ord (head y))
Any tips for the new guy?
Edit:
What I have been trying, for reference, is:
fc :: (Bool, [Char]) -> Int -> Integer
fc (x, y) = toInteger (ord (head y))
And I am getting the error above.
Your type signature is wrong. If you convert something you can't write it into the type signature. Only the last one is the return type. The others are parameter types.
Follow these:
fc::(Bool,[Char])->Integer
fc (x,y) = toInteger . ord . head $ y
fc::(Bool,[Char])->Int->Integer--
fc (x,y) n = if n == w then n else w
where w = toInteger . ord . head $ y
Edit:
The others mentioned currying what is absolutely correct if your teacher expect it. But the conversions doesn't take place in the type sign.
As n.m. says, the idea this is getting at is called currying. Basically, in Haskell, any function takes a single value and returns a single value: a -> b.
So, given this restriction, how can we implement functions like addition, which need two parameters? The answer is that we implement a function which takes a number, and returns another function which takes a number and returns a number. Laying it out this way might clarify things:
add :: Int -> Int -> Int
add x = f where f y = x + y
(which is equivalent to add x y = x + y, as well as add = (+)).
In your case, you should read the error carefully: Couldn't match expected type Int -> Integer with actual type Integer In the return type of a call of toInteger means that Haskell is expecting fc to return a value of type Int -> Integer, because that's what your type signature says, but the definition you've provided will always produce a value of type Integer.

What are the alternatives to prelude's iterate if the "output" values are not the same as those being iterated on?

I have come across a pattern where, I start with a seed value x and at each step generate a new seed value and a value to be output. My desired final result is a list of the output values. This can be represented by the following function:
my_iter :: (a -> (a, b)) -> a -> [b]
my_iter f x = y : my_iter f x'
where (x',y) = f x
And a contrived example of using this would be generating the Fibonacci numbers:
fibs:: [Integer]
fibs = my_iter (\(a,b) -> let c = a+b in ((b, c), c)) (0,1)
-- [1, 2, 3, 5, 8...
My problem is that I have this feeling that there is very likely a more idiomatic way to do this kind of stuff. What are the idiomatic alternatives to my function?
The only ones I can think of right now involve iterate from the Prelude, but they have some shortcomings.
One way is to iterate first and map after
my_iter f x = map f2 $ iterate f1 x
where f1 = fst . f
f2 = snd . f
However, this can look ugly if there is no natural way to split f into the separate f1 and f2 functions. (In the contrived Fibonacci case this is easy to do, but there are some situations where the generated value is not an "independent" function of the seed so its not so simple to split things)
The other way is to tuple the "output" values together with the seeds, and use a separate step to separate them (kind of like the "Schwartzian transform" for sorting things):
my_iter f x = map snd . tail $ iterate (f.fst) (x, undefined)
But this seems wierd, since we have to remember to ignore the generated values in order to get to the seed (the (f.fst) bit) and add we need an "undefined" value for the first, dummy generated value.
As already noted, the function you want is unfoldr. As the name suggests, it's the opposite of foldr, but it might be instructive to see exactly why that's true. Here's the type of foldr:
(a -> b -> b) -> b -> [a] -> b
The first two arguments are ways of obtaining something of type b, and correspond to the two data constructors for lists:
[] :: [a]
(:) :: a -> [a] -> [a]
...where each occurrence of [a] is replaced by b. Noting that the [] case produces a b with no input, we can consolidate the two as a function taking Maybe (a, b) as input.
(Maybe (a, b) -> b) -> ([a] -> b)
The extra parentheses show that this is essentially a function that turns one kind of transformation into another.
Now, simply reverse the direction of both transformations:
(b -> Maybe (a, b)) -> (b -> [a])
The result is exactly the type of unfoldr.
The underlying idea this demonstrates can be applied similarly to other recursive data types, as well.
The standard function you're looking for is called unfoldr.
Hoogle is a very useful tool in this case, since it doesn't only support searching functions by name, but also by type.
In your case, you came up with the desired type (a -> (a, b)) -> a -> [b]. Entering it yields no results - hmm.
Well, maybe there's a standard function with a slightly different syntax. For example, the standard function might have its arguments flipped; let's look for something with (a -> (a, b)) in its type signature somewhere. This time we're lucky as there are plenty of results, but all of them are in exotic packages and none of them seems very helpful.
Maybe the second part of your function is a better match, you want to generate a list out of some initial element after all - so type in a -> [b] and hit search. First result: unfoldr - bingo!
Another possibility is iterateM in State monad:
iterateM :: Monad m => m a -> m [a]
iterateM = sequence . repeat
It is not in standard library but it's easy to build.
So your my_iter is
evalState . sequence . repeat :: State s a -> s -> [a]

Creating a list type using functions

For a silly challenge I am trying to implement a list type using as little of the prelude as possible and without using any custom types (the data keyword).
I can construct an modify a list using tuples like so:
import Prelude (Int(..), Num(..), Eq(..))
cons x = (x, ())
prepend x xs = (x, xs)
head (x, _) = x
tail (_, x) = x
at xs n = if n == 0 then xs else at (tail xs) (n-1)
I cannot think of how to write an at (!!) function. Is this even possible in a static language?
If it is possible could you try to nudge me in the right direction without telling me the answer.
There is a standard trick known as Church encoding that makes this easy. Here's a generic example to get you started:
data Foo = A Int Bool | B String
fooValue1 = A 3 False
fooValue2 = B "hello!"
Now, a function that wants to use this piece of data must know what to do with each of the constructors. So, assuming it wants to produce some result of type r, it must at the very least have two functions, one of type Int -> Bool -> r (to handle the A constructor), and the other of type String -> r (to handle the B constructor). In fact, we could write the type that way instead:
type Foo r = (Int -> Bool -> r) -> (String -> r) -> r
You should read the type Foo r here as saying "a function that consumes a Foo and produces an r". The type itself "stores" a Foo inside a closure -- so that it will effectively apply one or the other of its arguments to the value it closed over. Using this idea, we can rewrite fooValue1 and fooValue2:
fooValue1 = \consumeA consumeB -> consumeA 3 False
fooValue2 = \consumeA consumeB -> consumeB "hello!"
Now, let's try applying this trick to real lists (though not using Haskell's fancy syntax sugar).
data List a = Nil | Cons a (List a)
Following the same format as before, consuming a list like this involves either giving a value of type r (in case the constructor was Nil) or telling what to do with an a and another List a, so. At first, this seems problematic, since:
type List a r = (r) -> (a -> List a -> r) -> r
isn't really a good type (it's recursive!). But we can instead demand that we first reduce all the recursive arguments to r first... then we can adjust this type to make something more reasonable.
type List a r = (r) -> (a -> r -> r) -> r
(Again, we should read the type List a r as being "a thing that consumes a list of as and produces an r".)
There's one final trick that's necessary. What we would like to do is to enforce the requirement that the r that our List a r returns is actually constructed from the arguments we pass. That's a little abstract, so let's give an example of a bad value that happens to have type List a r, but which we'd like to rule out.
badList = \consumeNil consumeCons -> False
Now, badList has type List a Bool, but it's not really a function that consumes a list and produces a Bool, since in some sense there's no list being consumed. We can rule this out by demanding that the type work for any r, no matter what the user wants r to be:
type List a = forall r. (r) -> (a -> r -> r) -> r
This enforces the idea that the only way to get an r that gets us off the ground is to use the (user-supplied) consumeNil function. Can you see how to make this same refinement for our original Foo type?
If it is possible could you try and nudge me in the right direction without telling me the answer.
It's possible, in more than one way. But your main problem here is that you've not implemented lists. You've implemented fixed-size vectors whose length is encoded in the type.
Compare the types from adding an element to the head of a list vs. your implementation:
(:) :: a -> [a] -> [a]
prepend :: a -> b -> (a, b)
To construct an equivalent of the built-in list type, you'd need a function like prepend with a type resembling a -> b -> b. And if you want your lists to be parameterized by element type in a straightforward way, you need the type to further resemble a -> f a -> f a.
Is this even possible in a static language?
You're also on to something here, in that the encoding you're using works fine in something like Scheme. Languages with "dynamic" systems can be regarded as having a single static type with implicit conversions and metadata attached, which obviously solves the type mismatch problem in a very extreme way!
I cannot think of how to write an at (!!) function.
Recalling that your "lists" actually encode their length in their type, it should be easy to see why it's difficult to write functions that do anything other than increment/decrement the length. You can actually do this, but it requires elaborate encoding and more advanced type system features. A hint in this direction is that you'll need to use type-level numbers as well. You'd probably enjoy doing this as an exercise as well, but it's much more advanced than encoding lists.
Solution A - nested tuples:
Your lists are really nested tuples - for example, they can hold items of different types, and their type reveals their length.
It is possible to write indexing-like function for nested tuples, but it is ugly, and it won't correspond to Prelude's lists. Something like this:
class List a b where ...
instance List () b where ...
instance List a b => List (b,a) b where ...
Solution B - use data
I recommend using data construct. Tuples are internally something like this:
data (,) a b = Pair a b
so you aren't avoiding data. The division between "custom types" and "primitive types" is rather artificial in Haskell, as opposed to C.
Solution C - use newtype:
If you are fine with newtype but not data:
newtype List a = List (Maybe (a, List a))
Solution D - rank-2-types:
Use rank-2-types:
type List a = forall b. b -> (a -> b -> b) -> b
list :: List Int
list = \n c -> c 1 (c 2 n) -- [1,2]
and write functions for them. I think this is closest to your goal. Google for "Church encoding" if you need more hints.
Let's set aside at, and just think about your first four functions for the moment. You haven't given them type signatures, so let's look at those; they'll make things much clearer. The types are
cons :: a -> (a, ())
prepend :: a -> b -> (a, b)
head :: (a, b) -> a
tail :: (a, b) -> b
Hmmm. Compare these to the types of the corresponding Prelude functions1:
return :: a -> [a]
(:) :: a -> [a] -> [a]
head :: [a] -> a
tail :: [a] -> [a]
The big difference is that, in your code, there's nothing that corresponds to the list type, []. What would such a type be? Well, let's compare, function by function.
cons/return: here, (a,()) corresponds to [a]
prepend/(:): here, both b and (a,b) correspond to [a]
head: here, (a,b) corresponds to [a]
tail: here, (a,b) corresponds to [a]
It's clear, then, that what you're trying to say is that a list is a pair. And prepend indicates that you then expect the tail of the list to be another list. So what would that make the list type? You'd want to write type List a = (a,List a) (although this would leave out (), your empty list, but I'll get to that later), but you can't do this—type synonyms can't be recursive. After all, think about what the type of at/!! would be. In the prelude, you have (!!) :: [a] -> Int -> a. Here, you might try at :: (a,b) -> Int -> a, but this won't work; you have no way to convert a b into an a. So you really ought to have at :: (a,(a,b)) -> Int -> a, but of course this won't work either. You'll never be able to work with the structure of the list (neatly), because you'd need an infinite type. Now, you might argue that your type does stop, because () will finish a list. But then you run into a related problem: now, a length-zero list has type (), a length-one list has type (a,()), a length-two list has type (a,(a,())), etc. This is the problem: there is no single "list type" in your implementation, and so at can't have a well-typed first parameter.
You have hit on something, though; consider the definition of lists:
data List a = []
| a : [a]
Here, [] :: [a], and (:) :: a -> [a] -> [a]. In other words, a list is isomorphic to something which is either a singleton value, or a pair of a value and a list:
newtype List' a = List' (Either () (a,List' a))
You were trying to use the same trick without creating a type, but it's this creation of a new type which allows you to get the recursion. And it's exactly your missing recursion which allows lists to have a single type.
1: On a related note, cons should be called something like singleton, and prepend should be cons, but that's not important right now.
You can implement the datatype List a as a pair (f, n) where f :: Nat -> a and n :: Nat, where n is the length of the list:
type List a = (Int -> a, Int)
Implementing the empty list, the list operations cons, head, tail, and null, and a function convert :: List a -> [a] is left as an easy exercise.
(Disclaimer: stole this from Bird's Introduction to Functional Programming in Haskell.)
Of course, you could represent tuples via functions as well. And then True and False and the natural numbers ...

Resources