This question is for amusement only. Please don't take this question too seriously.
I am currently learning F#, and I am interested to see if there is a concise way to define map4, using existing functions List.map2, List.map3, pipe forward/backward, forward/backward composition, etc.
i.e.
let map4 f a b c d = ......
map4 f [a1;a2] [b1;b2] [c1;c2] [d1;d2]
// output: [f(a1,b1,c1,d1); f(a2,b2,c2,d2)]
I can solve this recursively, or by defining a new operator (see the following URL)
http://www.fssnip.net/9W/title/nary-Seqmap-
http://call-with-cc-en.blogspot.sg/2009/04/applicative-functors-mapping-function.html
I can also solve this by combining List.map2 and List.map3, using partially applied functions f(a,b,?,?)
let map4 f a b c d =
List.map3 (fun g y -> g y) (List.map2 f a b) c d
I can try to shorten my code above using forward composition (and make it as abstract/confusing as possible)
let map4 f a =
List.map2 f a >> List.map3 id;;
// Output type: f:('a -> 'b -> 'c -> 'd -> 'e) ->
// a:'a list -> ('b list -> 'c list -> 'd list -> 'e list)
I would like to know if I can shorten it even further by getting rid of the "f" and "a", resulting in:
let map4 = ...... (* Use only List.map2, List.map3, |>, |<, >>, <<, etc.*) ..........
It will probably make it unnecessarily confusing, but it will be pretty cool. Thank you.
EDIT:
Adapting TheInnerLight's answer:
let inline (<!>) f xList = List.map f xList
let inline (<*>) gList xList = List.map2 (id) gList xList
let map4 f w x y z = f <!> w <*> x <*> y <*> z
let map5 f v w x y z = f <!> v <*> w <*> x <*> y <*> z
let map6 f u v w x y z = f <!> u <*> v <*> w <*> x <*> y <*> z
This is a good use for the applicative style of programming, i.e. using applicative functors.
Just define the apply function and some helper operators:
module List =
// val apply : f:('a -> 'b) list -> x:'a list -> 'b list
let apply f x = List.map2 (fun f x -> f x) f x
// val inline ( <!> ) : f:('a -> 'b) -> x:'a list -> 'b list
let inline (<!>) f x = List.map f x
// val inline ( <*> ) : f:('a -> 'b) list -> x:'a list -> 'b list
let inline (<*>) f x = apply f x
Then use map and apply to define mapN functions.
// val map2 : f:('a -> 'b -> 'c) -> x:'a list -> y:'b list -> 'c list
let map2 f x y = f <!> x <*> y
// val map3 : f:('a -> 'b -> 'c -> 'd) -> x:'a list -> y:'b list -> z:'c list -> 'd list
let map3 f x y z = f <!> x <*> y <*> z
// val map4 : f:('a -> 'b -> 'c -> 'd -> 'e) -> x:'a list -> y:'b list -> z:'c list -> a:'d list -> 'e list
let map4 f x y z a = f <!> x <*> y <*> z <*> a
// val map8 : f:('a -> 'b -> 'c -> 'd -> 'e -> 'f -> 'g -> 'h -> 'i) -> x:'a list -> y:'b list -> z:'c list -> a:'d list -> b:'e list -> c:'f list -> d:'g list -> e:'h list -> 'i list
let map8 f x y z a b c d e = f <!> x <*> y <*> z <*> a <*> b <*> c <*> d <*> e
As you can see, you can keep adding arguments to define arbitrary mapNs to your heart's content.
Since the question specifically asks about using map2 or map3, you can do this in the same style although it's a little less concise, e.g:
let map4_2 f x y z a = List.map2 f x y <*> z <*> a
let map4_3 f x y z a = List.map3 f x y z <*> a
Hopefully you get the idea.
As a small aside, I think it's worth noting that any monad is automatically an applicative functor, so there is a wide array of types you could use this pattern with, here is an Async example.
module Async =
// val map : f:('a -> 'b) -> x:Async<'a> -> Async<'b>
let map f x = async.Bind(x, async.Return << f)
// val apply : f:Async<('a -> 'b)> -> x:Async<'a> -> Async<'b>
let apply f x = async.Bind(f, fun fe -> map fe x)
// val inline ( <!> ) : f:('a -> 'b) -> x:Async<'a> -> Async<'b>
let inline (<!>) f x = map f x
// val inline ( <*> ) : f:Async<('a -> 'b)> -> x:Async<'a> -> Async<'b>
let inline (<*>) f x = apply f x
// val map4 : f:('a -> 'b -> 'c -> 'd -> 'e) -> x:Async<'a> -> y:Async<'b> -> z:Async<'c> -> a:Async<'d> -> Async<'e>
let map4 f x y z a = f <!> x <*> y <*> z <*> a
After lots of experimenting, I come up with the following "point-free" style answer:
// Warning: still have "Value Restriction" error
let map4 = List.map2 >> (>>) >> (|>) ((>>) >> (|>) (List.map3 id))
Unfortunately, the F# compiler will produce a "Value restriction" error, see:
https://blogs.msdn.microsoft.com/mulambda/2010/05/01/finer-points-of-f-value-restriction/
And so, I will settle with:
let map4 f =
f
|> ( List.map2 >> (>>) >> (|>) ((>>) >> (|>) (List.map3 id)) )
// val map4: f:('a->'b->'c->'d->'e) -> ('a list -> 'b list -> 'c list -> 'd list -> 'e list)
Related
I have the following code:
let orders = Array2D.init<AnalyzerOrder> (sentimentRanges |> Seq.length) (triggerRanges |> Seq.length) (fun x y -> AnalyzerOrder.empty)
sentimentRanges |> Seq.iteri (fun x sentimentPeriod ->
triggerRanges |> Seq.iteri (fun y triggerPeriod ->
(
let settings =
{
...
}
orders.[x, y] <- settings
)
)
)
It takes 2 sequences, and create an order list with all the combinations and put them in a grid.
Is there a built-in way to create all the combinations from 2 sequences?
When you look at the implementation of Seq.allPairs you will discover that it boils down to Seq.collect for the outer loop and Seq.cache/Seq.map for the inner. This can be generalized to two functions mapc/iterc, who take a function f:('a -> 'b -> 'c) or action f:('a -> 'b -> unit) as their first argument.
let mapc f xs ys = Seq.collect (fun x -> Seq.map (f x) (Seq.cache ys)) xs
// val mapc : f:('a -> 'b -> 'c) -> xs:seq<'a> -> ys:seq<'b> -> seq<'c>
let iterc f xs ys = Seq.iter (fun x -> Seq.iter (f x) (Seq.cache ys)) xs
// val iterc : f:('a -> 'b -> unit) -> xs:seq<'a> -> ys:seq<'b> -> unit
We could use them to generate the hyperinflation sequence for banknotes (OEIS A051109), or - more to the question - imperatively fill the values of an [,].
mapc (*) (Seq.initInfinite (pown 10I)) [1I; 2I; 5I] |> Seq.take 10 |> Seq.toList
// val it : System.Numerics.BigInteger list =
// [1; 2; 5; 10; 20; 50; 100; 200; 500; 1000]
let a2 = Array2D.zeroCreate 3 3
iterc (fun i j -> a2.[i,j] <- 1) [0..2] [0..2]
An example:
let initArray f s1 s2 = Array2D.init (Array.length s1) (Array.length s2) (fun a b -> f s1.[a] s2.[b] )
initArray (+) [|1;2;3|] [|1;2;3;4|] //where f is a sum function in this case
If you just to list all combinations, you can use the built-in function Seq.allPairs (exists in Array and List variants as well). If you want to create a two-dimensional array, you should do as #FRocha suggests.
I like using ROP when I have to deal with IO/Parsing strings/...
However let's say that I have a function taking 2 parameters. How can you do clean/readable partial application when your 2 parameters are already a Result<'a,'b> (not necessary same 'a, 'b)?
For now, what I do is that I use tuple to pass parameters and use the function below to get a Result of a tuple so I can then bind my function with this "tuple-parameter".
/// Transform a tuple of Result in a Result of tuple
let tupleAllResult x =
match (fst x, snd x) with
| Result.Ok a, Result.Ok b -> (a,b) |> Result.Ok
| Result.Ok a, Result.Error b -> b |> Result.Error
| Result.Error a, _ -> a |> Result.Error
let f (a: 'T, b: 'U) = // something
(A, B) |> tupleAllResult
|> (Result.bind f)
Any good idea?
Here what I wrote, which works but might not be the most elegant
let resultFunc (f: Result<('a -> Result<'b, 'c>), 'd>) a =
match f with
| Result.Ok g -> (g a) |> Result.Ok |> Result.flatten
| Result.Error e -> e |> Result.Error |> Result.flatten
I am not seeing partial application in your example, a concept related to currying and argument passing -- that's why I am assuming that you are after the monadic apply, in that you want to transform a function wrapped as a Result value into a function that takes a Result and returns another Result.
let (.>>.) aR bR = // This is "tupleAllResult" under a different name
match aR, bR with
| Ok a, Ok b -> Ok(a, b)
| Error e, _ | _, Error e -> Error e
// val ( .>>. ) : aR:Result<'a,'b> -> bR:Result<'c,'b> -> Result<('a * 'c),'b>
let (<*>) fR xR = // This is another name for "apply"
(fR .>>. xR) |> Result.map (fun (f, x) -> f x)
// val ( <*> ) : fR:Result<('a -> 'b),'c> -> xR:Result<'a,'c> -> Result<'b,'c>
The difference to what you have in your question is map instead of bind in the last line.
Now you can start to lift functions into the Result world:
let lift2 f xR yR =
Ok f <*> xR <*> yR
// val lift2 :
// f:('a -> 'b -> 'c) -> xR:Result<'a,'d> -> yR:Result<'b,'d> -> Result<'c,'d>
let res : Result<_,unit> = lift2 (+) (Ok 1) (Ok 2)
// val res : Result<int,unit> = Ok 3
I have been trying to implement church numerals in F#. They were briefly introduced in a course at college and I may have gone down the rabbit hole a bit since then. I have working Predecessor, Successor, Add and Operations but I can't get subtract to work. I'm trying to implement subtract b applying predecessor multiple times. What I find peculiar is that the penultimate line in my code works but what I assume is equivalent, the last line, does not work. There is a type mismatch.
I'm very new to F# so any help would be appreciated. Thank you.
//Operations on tuples
let fst (a,b) = a
let snd (a,b) = b
let pair a b = (a,b)
//Some church numerals
let c0 (f:('a -> 'a)) = id
let c1 (f:('a -> 'a)) = f
let c2 f = f << f
let c3 f = f << f << f
let c4 f = f << f << f << f
// Successor and predecessor
let cSucc (b,(cn:('a->'a)->('a->'a))) = if b then (b, fun f -> f << (cn f)) else (true, fun f -> (cn f))
let cPred (cn:('a->'a)->('a->'a)) = fun f -> snd (cn cSucc (false, c0)) f
//let cSucc2 cn = fun f -> f << (cn f)
// Add, Multiply and Subtract church numerals
let cAdd cn cm = fun f -> cn f << cm f
let cMult cn cm = cn >> cm
let cSub cn cm = cm cPred cn
//Basic function for checking validity of numeral operations
let f = (fun x -> x + 1)
//This works
(cPred << cPred) c3 f 0
//This doesn't
c2 cPred c3 f 0
This is the type mismatch error given (Intellisense says this is an error with cPred on the last line of the code). I can see the output type is inferred wrong. Is there a way to fix it or is there something fundamentally wrong with how I have written this implementation?
'((bool * (('a -> 'a) -> 'a -> 'a) -> bool * (('a -> 'a) -> 'a -> 'a)) -> bool * (('a -> 'a) -> 'a -> 'a) -> bool * (('a -> 'a) -> 'a -> 'a)) -> (bool * (('a -> 'a) -> 'a -> 'a) -> bool * (('a -> 'a) -> 'a -> 'a)) -> bool * (('a -> 'a) -> 'a -> 'a) -> bool * (('a -> 'a) -> 'a -> 'a)'
but given a
'((bool * (('a -> 'a) -> 'a -> 'a) -> bool * (('a -> 'a) -> 'a -> 'a)) -> bool * (('a -> 'a) -> 'a -> 'a) -> bool * (('a -> 'a) -> 'a -> 'a)) -> ('a -> 'a) -> 'a -> 'a'
The types ''a' and 'bool * (('a -> 'a) -> 'a -> 'a)' cannot be unified.
In the below explanation I will assume a definition of type CN<'a> = ('a -> 'a) -> 'a -> 'a (where "CN" stands for "Church Numeral") in order to shorten the explanation and reduce clutter.
Your attempted application of c2 to cPred fails, because c2 expects an argument of type 'a -> 'a, but cPred is not such function.
You may expect cPred to match the expected type, because you have declared it as CN<'a> -> CN<'a>, but that is not the true type. Because you are applying argument cn to type bool*CN<'a> -> bool*CN<'a> (which is the type of cSucc), the compiler infers that cn must have type of CN<bool*CN<'a>>, and therefore cPred gets the type of CN<bool*CN<'a>> -> CN<'a>, which does not match what c2 expects.
All of this comes down to this fact: functions lose their genericity when you pass them around as values.
Consider a simpler example:
let f (g: 'a -> 'a list) = g 1, g "a"
Such definition will not compile, because 'a is a parameter of f, not a parameter of g. Therefore, for a given execution of f, a specific 'a must be chosen, and it cannot be both int and string at the same time, and therefore, g cannot be applied to both 1 and "a".
Similarly, cn in cPred gets fixed to type bool*CN<'a> -> bool*CN<'a>, thus making the type of cPred itself incompatible with CN<_>.
In simple cases, there is an obvious workaround: pass g twice.
let f g1 g2 = g1 1, g2 "a"
let g x = [x]
f g g
// > it : int list * string list = [1], ["a"]
This way, g will lose genericity both times, but it will be specialized to different types - the first instance to int -> int list, the second - to string -> string list.
However, this is only a half-measure, suitable for the simplest cases only. A general solution will require the compiler to understand that we want 'a to be a parameter of g, not a parameter of f (this is usually referred to as "higher-rank type"). In Haskell (more specifically, GHC), there is a straightforward way to do this, with the RankNTypes extension enabled:
f (g :: forall a. a -> [a]) = (g 1, g "a")
g x = [x]
f g
==> ([1], ["a"])
Here, I explicitly tell the compiler that the parameter g has its own generic parameter a by including forall a in its type declaration.
F# does not have such explicit support for this, but it does offer a different feature that can be used to accomplish the same result - interfaces. Interfaces may have generic methods, and these methods do not lose genericity when interface instances are passed around. So we can reformulate the above simple example like this:
type G =
abstract apply : 'a -> 'a list
let f (g: G) = g.apply 1, g.apply "a"
let g = { new G with override this.apply x = [x] }
f g
// it : int list * string list = ([1], ["a"])
Yes, the syntax for declaring such "higher-rank functions" is heavy, but that's all F# has to offer.
So, applying this to your original problem, we need to declare CN as an interface:
type CN =
abstract ap : ('a -> 'a) -> 'a -> 'a
Then we can construct some numbers:
let c0 = { new CN with override __.ap f x = x }
let c1 = { new CN with override __.ap f x = f x }
let c2 = { new CN with override __.ap f x = f (f x) }
let c3 = { new CN with override __.ap f x = f (f (f x)) }
let c4 = { new CN with override __.ap f x = f (f (f (f x))) }
Then cSucc and cPred:
let cSucc (b,(cn:CN)) =
if b
then (b, { new CN with override __.ap f x = f (cn.ap f x) })
else (true, cn)
let cPred (cn:CN) = snd (cn.ap cSucc (false, c0))
Note that cPred now has inferred type of CN -> CN, exactly what we need.
Arithmetic functions:
let cAdd (cn: CN) (cm: CN) = { new CN with override __.ap f x = cn.ap f (cm.ap f x) }
let cMult (cn: CN) (cm: CN) = { new CN with override __.ap f x = cn.ap cm.ap f x }
let cSub (cn: CN) (cm: CN) = cm.ap cPred cn
Note, all of them get the inferred type of CN -> CN -> CN, as expected.
And finally, your examples:
let f = (fun x -> x + 1)
//This works
((cPred << cPred) c3).ap f 0
//This also works now
(c2.ap cPred c3).ap f 0
I am trying to express the Church encoding of the Free monad in F#. Free is specialized to a particular functor, Effect.
I am able to write both return_ : 'T -> Free<'T> and bind: ('T -> Free<'U>) -> Free<'T> -> Free<'U> without any problems.
A sketch of my implementation is given below.
type Effect<'T>
= GetStr of (string -> 'T)
| PutStr of string * 'T
module Effect =
let map (f: 'a -> 'b) : Effect<'a> -> Effect<'b> = function
| GetStr k ->
GetStr(f << k)
| PutStr (s,t) ->
PutStr(s, f t)
type Free<'T> =
abstract Apply : ('T -> 'R) -> (Effect<'R> -> 'R) -> 'R
module Free =
let inline runFree (f:Free<'T>) (kp: 'T -> 'R) (kf: Effect<'R> -> 'R) : 'R =
f.Apply kp kf
let return_ (x: 'a) : Free<'a> =
{ new Free<'a>
with
member __.Apply kp _ =
kp x
}
let bind (f: 'a -> Free<'b>) (m: Free<'a>) : Free<'b> =
{ new Free<'b>
with
member __.Apply kp kf =
runFree m
(fun a ->
runFree (f a) kp kf
)
kf
}
When I try to write an interpreter for this encoding, I hit a problem.
Given the following code:
module Interpret =
let interpretEffect = function
| GetStr k ->
let s = System.Console.ReadLine()
(k s , String.length s)
| PutStr(s,t) ->
do System.Console.WriteLine s
(t , 0)
let rec interpret (f: Free<string * int>) =
Free.runFree
f
(fun (str,len) -> (str,len))
(fun (a: Effect<Free<string*int>>) ->
let (b,n) = interpretEffect a
let (c,n') = interpret b
(c, n + n')
)
I get a type error in the third argument to Free.runFree within the interpret function:
...
(fun (a: Effect<Free<string*int>>) ->
^^^^^^^^^^^^^^^^^^ ------ Expecting a Effect<string * int> but given a Effect<Free<string*int>>
I understand why this is happening (the result type of the first function determines 'R === string*int) and suspect that can be solved using a rank-2 function (which can be encoded in F# e.g. http://eiriktsarpalis.github.io/typeshape/#/33) but I am not sure how to apply it.
Any pointers would be much appreciated.
Michael
You do not need to do anything there, the compiler suggested type is in fact correct (and in line with the type of runFree).
It seems that what you're thinking of there is Scott encoding (ripped from this Haskell question):
runFree :: Functor f => (a -> r) -> (f (F f a) -> r) -> F f a -> r
where F f a would be your Effect-specialised Free<'a>, and f (F f a) would be Effect<Free<'a>>, which is what you're trying to use.
Whereas Church encoding would be:
runFree :: Functor f => (a -> r) -> (f r -> r) -> F f a -> r
where f r is Effect<'a> - thus making it easier to express in F# (which is why I assume you're using it in the first place.
This is what I had for interpret:
let rec interpret (f: Free<string * int>) =
Free.runFree
f
(fun (str,len) -> (str,len))
(fun (a: Effect<_>) ->
let (b,n) = interpretEffect a
let (c,n') = interpret (Free.pureF b)
(c, n + n')
)
where pureF is
let pureF (x: 'a) : Free<'a> =
{ new Free<'a> with member __.Apply kp _ = kp x }
i.e. your return_ function.
I think defining the corresponding freeF function would clear some things (like why is Effect<'a> a functor - you're not making use of this fact anywhere in the code you pasted).
I would like to create a function map3 that, given a function f and a tuple (a, b, c) applies f to every member of the tuple. The expected signature of the function should be:
('a -> 'b) -> 'a * 'a * 'a -> 'b * 'b * 'b .
I tried several approaches:
> let map3 = fun x -> let f = fun (a, b, c) -> (a, b, c) in f x;;
val map3 : 'a * 'b * 'c -> 'a * 'b * 'c
> let map3 = fun x y -> x (let f = fun (a, b, c) -> (a, b, c) in f y);;
val map3 : x:('a * 'b * 'c -> 'd) -> 'a * 'b * 'c -> 'd
> let map3 = fun (x, y, z) -> let f = fun (a, b, c) -> (a, b, c) in f (x, y, z);;
val map3 : x:'a * y:'b * z:'c -> 'a * 'b * 'c
I strongly suspect that I did not get how function signatures actually work. According to what I get, map3 should have one input and one output, and f should take as input a triple and return a triple. But it is clearly wrong on something. What am I missing, in my attempts to implement it?
let map3 f (x, y, z) = (f x, f y, f z)
you can also write it like
let map3 f = fun (x, y, z) -> (f x, f y, f z)
or
let map3 = fun f (x, y, z) -> (f x, f y, f z)
But I would prefer to have the parameters on the left side. As you can see the first version is shorter to write and easier to read.