Can "bind" do a reduce on a List monad? - functional-programming

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

Related

Haskell map but remove items that don't follow condition

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.

How should I map over Maybe List?

I came away from Professor Frisby's Mostly Adequate Guide to Functional Programming with what seems to be a misconception about Maybe.
I believe:
map(add1, Just [1, 2, 3])
// => Just [2, 3, 4]
My feeling coming away from the aforementioned guide is that Maybe.map should try to call Array.map on the array, essentially returning Just(map(add1, [1, 2, 3]).
When I tried this using Sanctuary's Maybe type, and more recently Elm's Maybe type, I was disappointed to discover that neither of them support this (or, perhaps, I don't understand how they support this).
In Sanctuary,
> S.map(S.add(1), S.Just([1, 2, 3]))
! Invalid value
add :: FiniteNumber -> FiniteNumber -> FiniteNumber
^^^^^^^^^^^^
1
1) [1, 2, 3] :: Array Number, Array FiniteNumber, Array NonZeroFiniteNumber, Array Integer, Array ValidNumber
The value at position 1 is not a member of ‘FiniteNumber’.
In Elm,
> Maybe.map sqrt (Just [1, 2, 3])
-- TYPE MISMATCH --------------------------------------------- repl-temp-000.elm
The 2nd argument to function `map` is causing a mismatch.
4| Maybe.map sqrt (Just [1, 2, 3])
^^^^^^^^^^^^^^
Function `map` is expecting the 2nd argument to be:
Maybe Float
But it is:
Maybe (List number)
Similarly, I feel like I should be able to treat a Just(Just(1)) as a Just(1). On the other hand, my intuition about [[1]] is completely the opposite. Clearly, map(add1, [[1]]) should return [NaN] and not [[2]] or any other thing.
In Elm I was able to do the following:
> Maybe.map (List.map (add 1)) (Just [1, 2, 3])
Just [2,3,4] : Maybe.Maybe (List number)
Which is what I want to do, but not how I want to do it.
How should one map over Maybe List?
You have two functors to deal with: Maybe and List. What you're looking for is some way to combine them. You can simplify the Elm example you've posted by function composition:
> (Maybe.map << List.map) add1 (Just [1, 2, 3])
Just [2,3,4] : Maybe.Maybe (List number)
This is really just a short-hand of the example you posted which you said was not how you wanted to do it.
Sanctuary has a compose function, so the above would be represented as:
> S.compose(S.map, S.map)(S.add(1))(S.Just([1, 2, 3]))
Just([2, 3, 4])
Similarly, I feel like I should be able to treat a Just(Just(1)) as a Just(1)
This can be done using the join from the elm-community/maybe-extra package.
join (Just (Just 1)) == Just 1
join (Just Nothing) == Nothing
join Nothing == Nothing
Sanctuary has a join function as well, so you can do the following:
S.join(S.Just(S.Just(1))) == Just(1)
S.join(S.Just(S.Nothing)) == Nothing
S.join(S.Nothing) == Nothing
As Chad mentioned, you want to transform values nested within two functors.
Let's start by mapping over each individually to get comfortable:
> S.map(S.toUpper, ['foo', 'bar', 'baz'])
['FOO', 'BAR', 'BAZ']
> S.map(Math.sqrt, S.Just(64))
Just(8)
Let's consider the general type of map:
map :: Functor f => (a -> b) -> f a -> f b
Now, let's specialize this type for the two uses above:
map :: (String -> String) -> Array String -> Array String
map :: (Number -> Number) -> Maybe Number -> Maybe Number
So far so good. But in your case we want to map over a value of type Maybe (Array Number). We need a function with this type:
:: Maybe (Array Number) -> Maybe (Array Number)
If we map over S.Just([1, 2, 3]) we'll need to provide a function which takes [1, 2, 3]—the inner value—as an argument. So the function we provide to S.map must be a function of type Array (Number) -> Array (Number). S.map(S.add(1)) is such a function. Bringing this all together we arrive at:
> S.map(S.map(S.add(1)), S.Just([1, 2, 3]))
Just([2, 3, 4])

Recursive anonymous functions in SML

Is it possible to write recursive anonymous functions in SML? I know I could just use the fun syntax, but I'm curious.
I have written, as an example of what I want:
val fact =
fn n => case n of
0 => 1
| x => x * fact (n - 1)
The anonymous function aren't really anonymous anymore when you bind it to a
variable. And since val rec is just the derived form of fun with no
difference other than appearance, you could just as well have written it using
the fun syntax. Also you can do pattern matching in fn expressions as well
as in case, as cases are derived from fn.
So in all its simpleness you could have written your function as
val rec fact = fn 0 => 1
| x => x * fact (x - 1)
but this is the exact same as the below more readable (in my oppinion)
fun fact 0 = 1
| fact x = x * fact (x - 1)
As far as I think, there is only one reason to use write your code using the
long val rec, and that is because you can easier annotate your code with
comments and forced types. For examples if you have seen Haskell code before and
like the way they type annotate their functions, you could write it something
like this
val rec fact : int -> int =
fn 0 => 1
| x => x * fact (x - 1)
As templatetypedef mentioned, it is possible to do it using a fixed-point
combinator. Such a combinator might look like
fun Y f =
let
exception BlackHole
val r = ref (fn _ => raise BlackHole)
fun a x = !r x
fun ta f = (r := f ; f)
in
ta (f a)
end
And you could then calculate fact 5 with the below code, which uses anonymous
functions to express the faculty function and then binds the result of the
computation to res.
val res =
Y (fn fact =>
fn 0 => 1
| n => n * fact (n - 1)
)
5
The fixed-point code and example computation are courtesy of Morten Brøns-Pedersen.
Updated response to George Kangas' answer:
In languages I know, a recursive function will always get bound to a
name. The convenient and conventional way is provided by keywords like
"define", or "let", or "letrec",...
Trivially true by definition. If the function (recursive or not) wasn't bound to a name it would be anonymous.
The unconventional, more anonymous looking, way is by lambda binding.
I don't see what unconventional there is about anonymous functions, they are used all the time in SML, infact in any functional language. Its even starting to show up in more and more imperative languages as well.
Jesper Reenberg's answer shows lambda binding; the "anonymous"
function gets bound to the names "f" and "fact" by lambdas (called
"fn" in SML).
The anonymous function is in fact anonymous (not "anonymous" -- no quotes), and yes of course it will get bound in the scope of what ever function it is passed onto as an argument. In any other cases the language would be totally useless. The exact same thing happens when calling map (fn x => x) [.....], in this case the anonymous identity function, is still in fact anonymous.
The "normal" definition of an anonymous function (at least according to wikipedia), saying that it must not be bound to an identifier, is a bit weak and ought to include the implicit statement "in the current environment".
This is in fact true for my example, as seen by running it in mlton with the -show-basis argument on an file containing only fun Y ... and the val res ..
val Y: (('a -> 'b) -> 'a -> 'b) -> 'a -> 'b
val res: int32
From this it is seen that none of the anonymous functions are bound in the environment.
A shorter "lambdanonymous" alternative, which requires OCaml launched
by "ocaml -rectypes":
(fun f n -> f f n)
(fun f n -> if n = 0 then 1 else n * (f f (n - 1))
7;; Which produces 7! = 5040.
It seems that you have completely misunderstood the idea of the original question:
Is it possible to write recursive anonymous functions in SML?
And the simple answer is yes. The complex answer is (among others?) an example of this done using a fix point combinator, not a "lambdanonymous" (what ever that is supposed to mean) example done in another language using features not even remotely possible in SML.
All you have to do is put rec after val, as in
val rec fact =
fn n => case n of
0 => 1
| x => x * fact (n - 1)
Wikipedia describes this near the top of the first section.
let fun fact 0 = 1
| fact x = x * fact (x - 1)
in
fact
end
This is a recursive anonymous function. The name 'fact' is only used internally.
Some languages (such as Coq) use 'fix' as the primitive for recursive functions, while some languages (such as SML) use recursive-let as the primitive. These two primitives can encode each other:
fix f => e
:= let rec f = e in f end
let rec f = e ... in ... end
:= let f = fix f => e ... in ... end
In languages I know, a recursive function will always get bound to a name. The convenient and conventional way is provided by keywords like "define", or "let", or "letrec",...
The unconventional, more anonymous looking, way is by lambda binding. Jesper Reenberg's answer shows lambda binding; the "anonymous" function gets bound to the names "f" and "fact" by lambdas (called "fn" in SML).
A shorter "lambdanonymous" alternative, which requires OCaml launched by "ocaml -rectypes":
(fun f n -> f f n)
(fun f n -> if n = 0 then 1 else n * (f f (n - 1))
7;;
Which produces 7! = 5040.

Multiple set comprehension in a functional style

Does any one know of a function/idiom (in any language) that takes a set and returns two or more subsets, determined by one or more predicates?
It is easy to do this in an imperative style e.g:
a = b = []
for x in range(10):
if even(x):
a.append(x)
else:
b.append(x)
or slightly better:
[even(x) and a.append(x) or b.append(x) for x in range(10)]
Since a set comprehension returns a single list based upon a single predicate (and it effectively just a map) I think there ought to be something that splits the input into 2 or more bins based on either a binary predicate or multiple predicates.
The neatest syntax I can come up with is:
>> def partition(iterable, *functions):
>> return [filter(f,iterable) for f in functions]
>> partition(range(10), lambda x: bool(x%2), lambda x: x == 2)
[[1, 3, 5, 7, 9], [2]]
Searching for (a -> Bool) -> [a] -> ([a], [a]) on Hoogle yields Data.List.partition.
The partition function takes a predicate a list and returns the pair of lists of elements which do and do not satisfy the predicate, respectively; i.e.,
partition p xs == (filter p xs, filter (not . p) xs)
If you look at its source and translate to Python,
def partition(predicate, sequence):
def select((yes, no), value):
if predicate(value):
return (yes + [value], no)
else:
return (yes, no + [value])
return reduce(select, sequence, ([], []))
which is pretty nicely functional. Unlike the original, it's not lazy, but that's a bit trickier to pull off in Python.
Ruby's Enumerable mixin has a partition method that does what you describe.

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