Haskell map but remove items that don't follow condition - dictionary

The function should take a list of tuples, and return the ones that have sum > 5
Let's say I have the following code:
fn :: [(Int, Int)] -> [(Int, Int)]
fn tuples = map (\(x,y) -> if (x + y) > 5 then (x,y) else (0,0)) tuples
fn [(3,4), (4,4), (0,1)] returns [(3,4),(4,4),(0,0)] but really I just want it to return [(3,4),(4,4)]
Is this possible in haskell while still following the type signature?

What you're asking for is mapMaybe:
mapMaybe :: (a -> Maybe b) -> [a] -> [b]
base Data.Maybe
The mapMaybe function is a version of map which can throw out elements. In particular, the functional argument returns something of type Maybe b. If this is Nothing, no element is added on to the result list. If it is Just b, then b is included in the result list.
The smallest change to use it in your code would be:
import Data.Maybe
fn :: [(Int, Int)] -> [(Int, Int)]
fn tuples = mapMaybe (\(x,y) -> if (x + y) > 5 then Just (x,y) else Nothing) tuples
However, in this specific case, you don't actually transform, you just remove. If you don't plan on adding transformation later, filter is more suitable:
fn = filter (\(x,y) -> x+y > 5)

Bit of a weird question, but after the comment
I dont see a concept of “empty tuple” in haskell
I guess I see where you're coming from. Actually Haskell does have “empty tuples”: the unit type () is the type of “tuples with zero elements”. So what you're thinking of seems to be
fn tuples = map (\(x,y) -> if x + y > 5 then (x,y) else ()) tuples
But that doesn't work because () is a different type from (Int,Int). The elements of a list must all have the same type. Even if it did work, à la dynamic-types, the result of fn [(3,4), (4,4), (0,1)] would then actually be [(3,4), (4,4), ()]. I.e. you'd still get three elements, just one of them would be “boring”.
map does in fact by design guarantee to never change the number of elements in the list, only the values of their elements. So if that's what you want, you need to use a different function. The closest to your approach would be concatMap:
fn tuples = concatMap (\(x,y) -> if x + y > 5 then [(x,y)] else []) tuples
What happens here can also be described in two steps:
You map a function that generates a list for each element. The result is thus a list of lists.
You flatten that list.
So [(3,4), (4,4), (0,1)] -> [[(3,4)], [(4,4)], []] -> [(3,4), (4,4)].
Really though, there's no need to use a mapping step at all here – the elements are kept as they are eventually, so filter is the tool to use.

Related

Map List onto shifted self

I have finally found an excellent entry point into functional programming with elm, and boy, do I like it, yet I still lack some probably fundamental elegance concerning a few concepts.
I often find myself writing code similar to the one below, which seems to be doing what it should, but if someone more experienced could suggest a more compact and direct approach, I am sure that could give some valuable insights into this so(u)rcery.
What I imagine this could boil down to, is something like the following
(<-> is a vector subtraction operator):
edgeDirections : List Vector -> List Vector
edgeDirections corners = List.map2 (\p v -> p <-> v) corners (shiftr 1 corners)
but I don't really have a satisfying approach to a method that would do a shiftr.
But the rules of stackoverflow demand it, here is what I tried. I wrote an ugly example of a possible usage for shiftr (I absolutely dislike the Debug.crash and I am not happy about the Maybe):
Given a list of vectors (the corner points of a polygon), calculate the directional vectors by calculating the difference of each corner-vector to its previous one, starting with the diff between the first and the last entry in the list.
[v1,v2,v3] -> [v1-v3,v2-v1,v3-v2]
Here goes:
edgeDir : Vector -> ( Maybe Vector, List Vector ) -> ( Maybe Vector, List Vector )
edgeDir p ( v, list ) =
case v of
Nothing ->
Debug.crash ("nono")
Just vector ->
( Just p, list ++ [ p <-> vector ] )
edgeDirections : List Vector -> List Vector
edgeDirections corners =
let
last =
List.head <| List.reverse corners
in
snd <| List.foldl edgeDir ( last, [] ) corners
main =
show <| edgeDirections [ Vector -1 0, Vector 0 1, Vector 1 0 ]
I appreciate any insight into how this result could be achieved in a more direct manner, maybe using existing language constructs I am not aware of yet, or any pointers on how to lessen the pain with Maybe. The latter may Just not be possible, but I am certain that the former will a) blow me away and b) make me scratch my head a couple times :)
Thank you, and many thanks for this felicitous language!
If Elm had built-in init and last functions, this could be cleaner.
You can get away from all those Maybes by doing some pattern matching. Here's my attempt using just pattern matching and an accumulator.
import List exposing (map2, append, reverse)
shiftr list =
let shiftr' acc rest =
case rest of
[] -> []
[x] -> x :: reverse acc
(x::xs) -> shiftr' (x::acc) xs
in shiftr' [] list
edgeDirections vectors =
map2 (<->) vectors <| shiftr vectors
Notice also the shortened writing of the mapping function of (<->), which is equivalent to (\p v -> p <-> v).
Suppose Elm did have an init and last function - let's just define those quickly here:
init list =
case list of
[] -> Nothing
[_] -> Just []
(x::xs) -> Maybe.map ((::) x) <| init xs
last list =
case list of
[] -> Nothing
[x] -> Just x
(_::xs) -> last xs
Then your shiftr function could be shortened to something like:
shiftr list =
case (init list, last list) of
(Just i, Just l) -> l :: i
_ -> list
Just after I "hung up", I came up with this, but I am sure this can still be greatly improved upon, if it's even correct (and it only works for n=1)
shiftr : List a -> List a
shiftr list =
let
rev =
List.reverse list
in
case List.head rev of
Nothing ->
list
Just t ->
[ t ] ++ (List.reverse <| List.drop 1 rev)
main =
show (shiftr [ 1, 2, 3, 4 ] |> shiftr)

Map a list of options to list of strings

I have the following function in OCaml:
let get_all_parents lst =
List.map (fun (name,opt) -> opt) lst
That maps my big list with (name, opt) to just a list of opt. An option can contain of either None or Some value which in this case is a string. I want a list of strings with all my values.
I am a beginner learning OCaml.
I don't think filter and map used together is a good solution to this problem. This is because when you apply map to convert your string option to string, you will have the None case to deal with. Even if you know that you won't have any Nones because you filtered them away, the type checker doesn't, and can't help you. If you have non-exhaustive pattern match warnings enabled, you will get them, or you will have to supply some kind of dummy string for the None case. And, you will have to hope you don't introduce errors when refactoring later, or else write test cases or do more code review.
Instead, you need a function filter_map : ('a -> 'b option) -> 'a list -> 'b list. The idea is that this works like map, except filter_map f lst drops each element of lst for which f evaluates to None. If f evaluates to Some v, the result list will have v. You could then use filter_map like so:
filter_map (fun (_, opt) -> opt) lst
You could also write that as
filter_map snd lst
A more general example would be:
filter_map (fun (_, opt) ->
match opt with
| Some s -> Some (s ^ "\n")
| None -> None)
lst
filter_map can be implemented like this:
let filter_map f lst =
let rec loop acc = function
| [] -> List.rev acc
| v::lst' ->
match f v with
| None -> loop acc lst'
| Some v' -> loop (v'::acc) lst'
in
loop [] lst
EDIT For greater completeness, you could also do
let filter_map f lst =
List.fold_left (fun acc v ->
match f v with
| Some v' -> v'::acc
| None -> acc) [] lst
|> List.rev
It's a shame that this kind of function isn't in the standard library. It's present in both Batteries Included and Jane Street Core.
I'm going to expand on #Carsten's answer. He is pointing you the right direction.
It's not clear what question you're asking. For example, I'm not sure why you're telling us about your function get_all_parents. Possibly this function was your attempt to get the answer you want, and that it's not quite working for you. Or maybe you're happy with this function, but you want to do some further processing on its results?
Either way, List.map can't do the whole job because it always returns a list of the same length as its input. But you need a list that can be different lengths, depending on how many None values there are in the big list.
So you need a function that can extract only the parts of a list that you're interested in. As #Carsten says, the key function for this is List.filter.
Some combination of map and filter will definitely do what you want. Or you can just use fold, which has the power of both map and filter. Or you can write your own recursive function that does all the work.
Update
Maybe your problem is in extracting the string from a string option. The "nice" way to do this is to provide a default value to use when the option is None:
let get default xo =
match xo with
| None -> default
| Some x -> x
# get "none" (Some "abc");;
- : string = "abc"
# get "none" None;;
- : string = "none"
#
type opt = Some of string | None
List.fold_left (fun lres -> function
(name,Some value) -> value::lres
| (name,None) -> lres
) [] [("s1",None);("s2",Some "s2bis")]
result:
- : string list = ["s2bis"]

Writing a function that is sum of functions

I have the following excercise to do:
Code a function that will be a summation of a list of functions.
So I think that means that if a function get list of functions [f(x);g(x);h(x);...] it must return a function that is f(x)+g(x)+h(x)+...
I'm trying to do code that up for the general case and here's something I came up with:
let f_sum (h::t) = fold_left (fun a h -> (fun x -> (h x) + (a x))) h t;;
The problem is I'm using "+" operator and that means it works only when in list we have functions of type
'a -> int
So, can it be done more "generally", I mean can we write a function, that is a sum of ('a -> 'b) functions, given in a list?
yes, you can make plus function to be a parameter of your function, like
let f_sum plus fs =
let (+) = plus in
match fs with
| [] -> invalid_arg "f_sum: empty list"
| f :: fs -> fold_left ...
You can generalize even more, and ask a user to provide a zero value, so that you can return a function, returning zero if the list is empty. Also you can use records to group functions, or even first class modules (cf., Commutative_group.S in Core library).

Can "bind" do a reduce on a List monad?

I know how to do the equivalent of Scheme's (or Python's) map and filter functions with the list monad using only the "bind" operation.
Here's some Scala to illustrate:
scala> // map
scala> List(1,2,3,4,5,6).flatMap {x => List(x * x)}
res20: List[Int] = List(1, 4, 9, 16, 25, 36)
scala> // filter
scala> List(1,2,3,4,5,6).flatMap {x => if (x % 2 == 0) List() else List(x)}
res21: List[Int] = List(1, 3, 5)
and the same thing in Haskell:
Prelude> -- map
Prelude> [1, 2, 3, 4, 5, 6] >>= (\x -> [x * x])
[1,4,9,16,25,36]
Prelude> -- filter
Prelude> [1, 2, 3, 4, 5, 6] >>= (\x -> if (mod x 2 == 0) then [] else [x])
[1,3,5]
Scheme and Python also have a reduce function that's often grouped with map and filter. The reduce function combines the first two elements of a list using the supplied binary function, and then combines that result the the next element, and then so on. A common use to to compute the sum or product of a list of values. Here's some Python to illustrate:
>>> reduce(lambda x, y: x + y, [1,2,3,4,5,6])
21
>>> (((((1+2)+3)+4)+5)+6)
21
Is there any way to do the equivalent of this reduce using just the bind operation on a list monad? If bind can't do this on its own, what's the most "monadic" way to perform this operation?
If possible, please limit/avoid the use of syntactic sugar (ie: do notation in Haskell or sequence comprehensions in Scala) when answering.
One of the defining properties of the bind operation is that the result is still "inside" the monad¹. So when you perform bind on a list, the result will again be a list. Since the reduce operation² often results in something other than a list, it can't be expressed in terms of the bind operation.
In addition to that the bind operation on lists (i.e. concatMap/flatMap) only looks at one element at a time and offers no way of reusing the result of previous steps. So even if we're okay with getting the result wrapped in a single-element list, there's no way to do it just with monad operations.
¹ So if you have a type that allows you to perform no operations on it except the ones defined by the monad type class, you can never "break out" of the monad. That's what makes the IO monad works.
² Which is called fold in Haskell and Scala by the way.
If bind can't do this on its own, what's the most "monadic" way to perform this operation?
While the answer given by #sepp2k is correct, there is a way to do a reduce-like operation on a list monadically, but using the product or "writer" monad and an operation which corresponds to distributing the product monad over the list functor.
The definition is:
import Control.Monad.Writer.Lazy
import Data.Monoid
reduce :: Monoid a => [a] -> a
reduce xs = snd . runWriter . sequence $ map tell xs
Let me unpack:
The Writer monad has a data type Writer w a which is basically a tuple (product) of a value a and "written" value w. The type of written values w must be a monoid where the bind operation of the Writer monad is defined something like:
(w, a) >>= f = let (w', b) = f a in (mappend w w', b)
i.e. take the incoming written value, and the result written value, and combine them using the binary operation of the monoid.
The tell operation writes a value, tell :: w -> Writer w (). Thus map tell has type [a] -> [Writer a ()] i.e. a list of monadic values where each element of the original list has been "written" in the monad.
sequence :: Monad m => [m a] -> m [a] corresponds to a distributive law between lists and monads i.e. distribute the monad type over the list type; sequence can be defined in terms of bind as:
sequence [] = return []
sequnece (x:xs) = x >>= (\x' -> (sequence xs) >>= (\xs' -> return $ x':xs'))
(actually the implementation in Prelude uses foldr, a clue to the reduction-like usage)
Thus, sequence $ map tell xs has type Writer a [()]
The runWriter operation unpacks the Writer type, runWriter :: Writer w a -> (a, w),
which is composed here with snd to project out the accumulated value.
An example usage on lists of Ints would be to use the monoid instance:
instance Monoid Int where
mappend = (+)
mempty = 0
then:
> reduce ([1,2,3,4]::[Int])
10

Ocaml continuation passing style

I'm new to ocaml and tryin to write a continuation passing style function but quite confused what value i need to pass into additional argument on k
for example, I can write a recursive function that returns true if all elements of the list is even, otherwise false.
so its like
let rec even list = ....
on CPS, i know i need to add one argument to pass function
so like
let rec evenk list k = ....
but I have no clue how to deal with this k and how does this exactly work
for example for this even function, environment looks like
val evenk : int list -> (bool -> ’a) -> ’a = <fun>
evenk [4; 2; 12; 5; 6] (fun x -> x) (* output should give false *)
The continuation k is a function that takes the result from evenk and performs "the rest of the computation" and produces the "answer". What type the answer has and what you mean by "the rest of the computation" depends on what you are using CPS for. CPS is generally not an end in itself but is done with some purpose in mind. For example, in CPS form it is very easy to implement control operators or to optimize tail calls. Without knowing what you are trying to accomplish, it's hard to answer your question.
For what it is worth, if you are simply trying to convert from direct style to continuation-passing style, and all you care about is the value of the answer, passing the identity function as the continuation is about right.
A good next step would be to implement evenk using CPS. I'll do a simpler example.
If I have the direct-style function
let muladd x i n = x + i * n
and if I assume CPS primitives mulk and addk, I can write
let muladdk x i n k =
let k' product = addk x product k in
mulk i n k'
And you'll see that the mulptiplication is done first, then it "continues" with k', which does the add, and finally that continues with k, which returns to the caller. The key idea is that within the body of muladdk I allocated a fresh continuation k' which stands for an intermediate point in the multiply-add function. To make your evenk work you will have to allocate at least one such continuation.
I hope this helps.
Whenever I've played with CPS, the thing passed to the continuation is just the thing you would normally return to the caller. In this simple case, a nice "intuition lubricant" is to name the continuation "return".
let rec even list return =
if List.length list = 0
then return true
else if List.hd list mod 2 = 1
then return false
else even (List.tl list) return;;
let id = fun x -> x;;
Example usage: "even [2; 4; 6; 8] id;;".
Since you have the invocation of evenk correct (with the identity function - effectively converting the continuation-passing-style back to normal style), I assume that the difficulty is in defining evenk.
k is the continuation function representing the rest of the computation and producing a final value, as Norman said. So, what you need to do is compute the result of v of even and pass that result to k, returning k v rather than just v.
You want to give as input the result of your function as if it were not written with continuation passing style.
Here is your function which tests whether a list has only even integers:
(* val even_list : int list -> bool *)
let even_list input = List.for_all (fun x -> x mod 2=0) input
Now let's write it with a continuation cont:
(* val evenk : int list -> (bool -> 'a) -> 'a *)
let evenk input cont =
let result = even_list input in
(cont result)
You compute the result your function, and pass resultto the continuation ...

Resources