I have a function defined
maybeToList :: (a -> Maybe a) -> a -> [a]
maybeToList f x = x : maybe [] (maybeToList f) (f x)
This function seems so obvious that I can't believe it is not standard.
Is it defined in some module (I already checked Data.Maybe)?
Your function isn't in the standard libraries because it's a specialized form of one that is:
unfoldr :: (b -> Maybe (a, b)) -> b -> [a]
unfoldr f b =
case f b of
Just (a,new_b) -> a : unfoldr f new_b
Nothing -> []
That said, the case where the list elements are the same as the sequence of seed values is common, and it's clumsy to write in terms of just unfoldr and other standard functions, so I'm not sure why it's not in the standard libraries as well.
Related
Now I have this code that takes a list and does something to the first element and then to every other one. And it returns a list of the transformed elements. The problem I am having is that I want to have a list that contains the untransformed and the transformed elements. This is what I have so far:
applyToEveryOther :: (a -> b) -> [a] -> [b]
applyToEveryOther _ [] = []
applyToEveryOther f [x] = [f x]
applyToEveryOther f (x:y:xs) = f x : y : applyToEveryOther f xs
The error it is giving me says there is a problem with the : y part of the function
When I try your code, I get the following (admittedly somewhat lengthy and confusing) error message:
EveryOther.hs:4:42: error:
• Couldn't match type ‘b’ with ‘a’
‘b’ is a rigid type variable bound by
the type signature for:
applyToEveryOther :: forall a b. (a -> b) -> [a] -> [b]
at EveryOther.hs:1:22
‘a’ is a rigid type variable bound by
the type signature for:
applyToEveryOther :: forall a b. (a -> b) -> [a] -> [b]
at EveryOther.hs:1:22
Expected type: [a]
Actual type: [b]
• In the second argument of ‘(:)’, namely ‘applyToEveryOther f xs’
In the second argument of ‘(:)’, namely
‘y : applyToEveryOther f xs’
In the expression: f x : y : applyToEveryOther f xs
• Relevant bindings include
xs :: [a] (bound at EveryOther.hs:4:26)
y :: a (bound at EveryOther.hs:4:24)
x :: a (bound at EveryOther.hs:4:22)
f :: a -> b (bound at EveryOther.hs:4:19)
applyToEveryOther :: (a -> b) -> [a] -> [b]
(bound at EveryOther.hs:2:1)
However, it's worth trying to figure out what GHC is saying here. As per the second bullet point, GHC was processing the subexpression y : applyToEveryOther f xs, and specifically looking at the second argument to the : operator in that expression (namely applyToEveryOther f xs. It expected that expression to have type [a], but the actual type of the expression was type [b].
Here, a and b are both "rigid" types, meaning simply that they were specified explicitly by the programmer. GHC also notes, in the relevant bindings, that y had type a.
So, to sum up, you asked GHC to evaluate the expression:
y : applyToEveryOther f xs
where you already specified that y had type a and applyToEveryOther f xs had type [b], and GHC refused to do this because lists in Haskell can't mix two different types.
And that's kind of the key to the whole problem. You want to transform some of the elements of your [a] list from a to b, but then you want to return a mixed list of as and bs. Haskell can't do that!
The only way your function can work is if you change the signature so that a and b are the same type:
applyToEveryOther :: (a -> a) -> [a] -> [a]
and your code will work fine.
Another way you could "discover" the correct signature is to leave it out and have Haskell infer the most general possible signature. If you load the code (without the explicit signature) into GHCi and ask for the type, you get:
> :t applyToEveryOther
applyToEveryOther :: (a -> a) -> [a] -> [a]
>
which is the most general possible type for this function.
If I understood correctly you wanted both, the original and transformed values.
However evaluating applyToEveryOther (+3) [0,1,2] returns [3,1,5]. If you want [0,3,1,4,2,5] as a result, try
applyToEveryOther _ [] = []
applyToEveryOther f [x] = [x,f x]
applyToEveryOther f (x:xs) = x: f x : applyToEveryOther f xs
I have a function:
sum f l1 l2 = (f l1) + (f l2)
How to correct this function to be working when called with different types of lists? eg:
sum length [1,2] ['a','b']
May as well flesh out my comment in an answer. The usual signature one may be tempted to give is
sum :: Num b => ([a] -> b) -> [a] -> [a] -> b
sum f l1 l2 = f l1 + f l2
The problem here is that the two lists must have the same type, which must be the input type of the function. The solution is to tell GHC that the function actually has the more general type forall a. [a] -> b, which means that we can pick multiple possibly different a instantiations and they all produce the same b.
{-# LANGUAGE RankNTypes #-}
sum' :: Num b => (forall a. [a] -> b) -> [c] -> [d] -> b
sum' f l1 l2 = f l1 + f l2
main = print $ sum' length [1,2] ['a','b']
There's no general way to do this at the moment unfortunately. You could try like this previous answer suggested as follows:
sum' :: Num b => (forall a. [a] -> b) -> [c] -> [d] -> b
sum' f l1 l2 = f l1 + f l2
And whilst this works with length, it doesn't really work with much else.
The issue is that the type signature in this answer Num b => forall a. [a] -> b. That means your function must work for all types of lists, and the only sensible function from Num b => forall a. [a] -> b is length. If you think there's another feel free to give me an example, but I suspect all the other examples are either variations of length or silly ones that return a constant.
And if length is the only sensible argument for sum', then it's silly to define sum', you might as well define sumLength like follows
sumLength :: Num b => [c] -> [d] -> b
sumLength l1 l2 = genericLength l1 + genericLength l2
Indeed, lets define the following:
g :: Enum a => [a] -> Int
g = (foldl' 0 (+)) . (map fromEnum)
This is a weird probably useless function, but it does something non-trivial. It converts all the values to their Enum int representation and sums them and spits out an Integer.
So sum' g l1 l2 should work, but it doesn't. To get this to work, you'd have to define a new function:
sum'' :: Enum c, Enum d => (Enum a => forall a. [a]) -> [c] -> [d] -> Int
sum'' f l1 l2 = f l1 + f l2
And indeed, too use any function with different constraints, you'll have to define a new version of sum.
So really, no, there's no way to answer your question similarly.
I recognised this problem and created the package polydata, which you can check out on hackage (needs some clearer documentation I admit).
It does allow you to make functions which accept polymorphic functions that you can apply to different types, like so:
g :: (c (a -> a'), c (b -> b')) => Poly c -> (a, b) -> (a' -> b')
g f (x,y) = (getPoly f x, getPoly f y)
Which is very similar to your example.
c in the above is a constraint, and looking at the type of g should help you understand what's happening.
Unfortunately, you can't just pass an ordinary function to g, you have to pass one wrapped in a Poly, which is non trivial as you don't get type inference for the Poly constraint (any ideas on how to make this nicer appreciated).
But if you've just got one or a few functions that need this polymorphic behaviour, I wouldn't bother with Poly. But for example, you're finding this issue coming up a lot (I found it came up a lot in unit testing, which is what inspired the creation of my package), then you might find polydata useful.
There's also heterolist, which I created as an extension to polydata allows you to create lists of mixed types and say, map over them in a type safe way. You might find that useful.
I was wondering what the best way is to implement the following problem in a functional programming language (in this example Haskell):
You have a function (or a 'way') that turns 2 inputs, with the type a and b, in 2 ouputs of the same type (ex: Half adder). Lets call it f
in Haskell it would have this sort of type signature
a -> b -> (a, b)
And you have a list with elements of type a. (or another type of data structure).
Now if supplied with an initial b I want the following thing to happen (concept explained with recursive implementation):
Execute f with the initial b and the first element, modify the b and the element with the output of the function and repeat for the next element.
In Haskell:
exec _ [] _ = []
exec f (x:xs) b = let (x',b') = f x b in x':(exec f xs b')
What would be the best/most efficient way to model this sort of behavior.
It's mapM for the State monad.
OK, expanding a little.
Let's first enter this into ghci and see the type of the exec function:
Prelude> let {exec _ [] _ = []; exec f (x:xs) b = let (x',b') = f x b in x':(exec f xs b')}
Prelude> :t exec
exec :: (t2 -> t1 -> (t, t1)) -> [t2] -> t1 -> [t]
It's almost as you described, except that t and t2 don't have to be of the same type. That's good.
Now, another observation: we actually lose information, when we do what you describe. Specifically, we throw away the last value of b (or t, as ghci calls it). Let us preserve it for a moment; we can always throw it away later:
exec' _ [] b = ([], b)
exec' f (x:xs) b =
let (x',b') = f x b
(xs', b'') = exec' f xs b'
in (x':xs', b'')
And ghci says
Prelude> :t exec'
exec' :: (t2 -> t1 -> (t, t1)) -> [t2] -> t1 -> ([t], t1)
Than we can define
exec f xs b = fst $ exec' f xs b
But now the type of exec' contains a clear pattern. We can make it more explicit:
type S b c = b -> (c, b)
exec' :: (a -> S b c) -> [a] -> S b [c]
And now it's clear that S is almost exactly the State monad (well, it's actual definition in a modern setting is a bit more complicated, but not much: https://hackage.haskell.org/package/mtl-2.2.1/docs/Control-Monad-State-Lazy.html#t:StateT); really, it's just a newtype:
newtype State b c = State {runState :: b -> (c, b)}
And if we generalize the type of exec' to use an arbitrary monad instead of State, we get
Monad m => (a -> m c) -> [a] -> m [c]
Of course, we can't know for sure that such a thing actually exists, since we only have an implementation for the State monad, but... it does. It's called mapM (again, it's actual definition in the modern setting is more complicated: https://hackage.haskell.org/package/base-4.9.1.0/docs/Prelude.html#v:mapM) — which makes sense, since without a monad it would be just
(a -> c) -> [a] -> [c]
and that's exactly the type of map.
Of course, you can't be sure that exec' IS mapM without examining the latter's implementation. But in Haskell it just often happens that things that have the same type, if it's reasonably generic, are one and the same.
It also makes sense that State monad would be involved somehow — after all, you DO use b as a state, changing it as you go through the list.
So, if exec' is mapM, how do we get back to exec? Well, we need to go from the monadic value State b [c] to just [c], feeding it some b. We can — again — generalize; let's say, we go from State b d to d, without mentioning the list. And again — there is a function like that, it's called evalState: https://hackage.haskell.org/package/mtl-2.2.1/docs/Control-Monad-State-Lazy.html#v:evalState.
So, finally, we are able to produce the final result:
eval f xs b = evalState (mapM (\x -> state (\b -> f x b)) xs) b
which we can shorten to
eval f xs b = evalState (mapM (\x -> state (f x)) xs) b
or just
eval f xs = evalState (mapM (state . f) xs)
or even
eval f = evalState . mapM (state . f)
We can make it completely point-free, but that would be pointless (and contain too many points):
eval = (evalState .) . mapM . (state .)
I've tried to go through this using the types, but I'm still having difficulty understanding how it works.
Given:
> :t (==)
(==) :: Eq a => a -> a -> Bool
> :t (<*>)
(<*>) :: Applicative f => f (a -> b) -> f a -> f b
> :t reverse
reverse :: [a] -> [a]
> :t (==) <*> reverse
(==) <*> reverse :: Eq a => [a] -> Bool
Intuitively I can understand that it combines the equality operator with reverse in such a way that it creates a function that checks if a reversed list is equal to the original, but that's really not much more information than what is already pretty obvious.
Could someone break down in more detail the internals of what is actually happening here?
Start with the type of (<*>)
> : t (<*>)
(<*>) :: Applicative f => f (a -> b) -> f a -> f b
Now (->) k is an instance of Applicative, with implementation
instance Applicative ((->) k) where
pure a = \_ -> a
f <*> g = \k -> f k (g k)
In particular, the type of (<*>) specialised to (->) k is
(<*>) :: (k -> a -> b) -> (k -> a) -> (k -> b)
So the application (==) <*> reverse is
(==) <*> reverse = \k -> (==) k (reverse k)
= \k -> k == reverse k
i.e. it checks that a list is equal to its reverse.
Chris Taylor's answer is just right, but another way of looking at it, that I find more intuitive, is this: what the Applicative instance of function types does is this:
"Feed" the same argument value to two functions with the same argument type;
Combine their results with another function.
So basically, if you have f :: t -> a and g:: t -> b, the Applicative instance lets you map functions h :: a -> b -> c over the a and b results, under the assumption that f and g will be fed the same argument.
So think of how you'd write the palindrome test in a non-convoluted way:
palindrome :: Eq a => [a] -> Bool
palindrome xs = xs == reverse xs
xs appears twice on the right hand side of the definition: once as argument to ==, and a second time as argument to reverse. This automatically tells you that there is likely a way to use the (->) t applicative instance to eliminate the duplication. A different, perhaps more intuitive attack on this would be to first rewrite the function to this:
palindrome xs = id xs == reverse xs
...where id x = x is the identity function, which just returns its argument (and is a standard library function). Now you can rewrite that using the standard Applicative idiom (f <$> a0 <*> ... <*> an) to this:
-- Function that feed the same argument value to both `id` and `reverse`,
-- then tests their results with `==`:
palindrome = (==) <$> id <*> reverse
And now we can ask if there is a way to get rid of id in that rewrite. Since <$> is just shorthand for fmap, we can study the Functor instance for (->) t, which is just another way to express function composition:
instance Functor ((->) t) where
-- Mapping `f` over a *function* `g` is just the same as composing `f`
-- on the results of `g`.
fmap f g = f . g
One of the most important properties of function composition is that for any function f:
f . id = f
So applying that to the version of palindrome above, we get:
-- Since `f . id = f` for all `f`, then `(==) <$> id` is just `(==)`:
palindrome = (==) <*> reverse
I can't figure this, I have a type called Enumeration
> type Enumeration a = Int -> [a]
And I need to map over it. I wrote this following function:
> imapE :: (a -> b) -> Enumeration a -> Enumeration b
> imapE f (m fa) = \n -> imapF f fa
where imapF is defined like this:
> imapF :: (a -> b) -> [a] -> [b]
> imapF _ [] = []
> imapF f (x:xs) = f x : imapF f xs
but when I try to load my code I get the following error BinaryTrees.lhs:91:14: Parse error in pattern: m regarding my imapE function.
I am trying to get the first enumeration Enumeration a as the function it is (Int and [a])
You cannot pattern match over a function, but you don't have to do that:
> imapE :: (a -> b) -> Enumeration a -> Enumeration b
> imapE f g = (imapF f) . g
(Well, imapF is just map really).
Without using .:
> imapE :: (a -> b) -> Enumeration a -> Enumeration b
> imapE f g = \n -> imapF f (g n)
A possible solution could be
imapE :: (a -> b) -> Enumeration a -> Enumeration b
imapE = map . map
Indeed, the above is equivalent to
imapE f = map (map f)
where
f :: a -> b
map f :: [a] -> [b]
map (map f) :: (Int -> [a]) -> (Int -> [b])
since both [] and (->) Int are functors.
The main "trick" to this kind of exercises is to think more about the types than the actual values.
This might feel a bit obscure if you're a beginner. Once you'll get more familiar with functors, however, this will become quite natural.
(People very accustomed to this style could even hint to this solution with some cryptic note "functors compose", and leaving you to figure out what's really going on. When that happens, don't give up -- eventually it will make sense ;-))