These are chat archives for Microsoft/visualfsharp

20th
Feb 2017
Robert Maxton
@robertmaxton42
Feb 20 2017 12:08
So I'm having some trouble getting FAKE to properly unify certain higher-order function values
Let's say I define
let plus a b c = a + b + c 
let times a b = a * b 

val plus : a:int -> b:int -> c:int -> int
val times : a:int -> b:int -> int
and then I try to define, say, a five-times-plus-er times 5 << plus that takes three values, sums them, and multiplies the total by five, I get
> let plustimes = times 5 << plus;;

Testing.fsx(12,28): error FS0001: Type mismatch. Expecting a
    int -> int
but given a
    int -> int -> int -> int
The type 'int' does not match the type 'int -> int -> int'
Is this just a limitation of the unifier, or am I missing a keyword?
Robert Maxton
@robertmaxton42
Feb 20 2017 12:16
(I know I could just explicitly define plustimes to take three arguments and then tack them on to the end, but that doesn't feel very elegant/functional-y)
Robert Maxton
@robertmaxton42
Feb 20 2017 12:34
Actually, sorry, no, I have to tell it to take two arguments so that the last function is properly a first-order function
which is very confusing to read
Steffen Forkmann
@forki
Feb 20 2017 12:40
try to define it in non-point-free style first
something like:
let plustimes a b = times 5 a |> plus b
Robert Maxton
@robertmaxton42
Feb 20 2017 12:44
er? the problem here is when the multi-valued function is at the end
if the last function takes one parameter/is first-order, then it works fine
Yemi Bedu @ P&R
@pr-yemibedu
Feb 20 2017 15:04
"<<" and ">>" is to compose over a matching input to output. http://fssnip.net/S
Robert Maxton
@robertmaxton42
Feb 20 2017 15:11
Mm. Unfortunate. So I do have to make the composition explicit, huh. Oh well.
Yemi Bedu @ P&R
@pr-yemibedu
Feb 20 2017 15:11
you just have to make the functions compatible.
Robert Maxton
@robertmaxton42
Feb 20 2017 15:13
well sure, but it doesn't seem to recognize an 'a->'b->'c type as compatible with a 'c type.
Yemi Bedu @ P&R
@pr-yemibedu
Feb 20 2017 15:15
that is not composition of monoids. you want to pipe values to functions it seems.
Robert Maxton
@robertmaxton42
Feb 20 2017 15:15
I would like to pump function values to functions, to be precise, but yes
I'd like to take a 'a->'b type and combine it with a 'c->'d->'a type to get a 'c->'d->'b type
Yemi Bedu @ P&R
@pr-yemibedu
Feb 20 2017 15:21
let mul (a, b) = a * b
let sum a b c = a + b + c
let mulsum = mul >> sum
Robert Maxton
@robertmaxton42
Feb 20 2017 15:23
okay, but now we're cheating by setting the first function to take a tuple.
like if the language can't do this I can just set the parameters explicitly, I was just wondering if there's a better way
Yemi Bedu @ P&R
@pr-yemibedu
Feb 20 2017 15:24
maybe I do not understand, can you show it working in another language?
not just plain math
Robert Maxton
@robertmaxton42
Feb 20 2017 15:24
Not in particular that i can think of. It might work in OcaML, a lot of stuff works in OcaML :P
Yemi Bedu @ P&R
@pr-yemibedu
Feb 20 2017 15:25
f# is ocaml in many ways
Robert Maxton
@robertmaxton42
Feb 20 2017 15:25
I'm pretty sure it does work in Coq but I haven't touched Coq in years
so the definition is that ">>" and "<<" are only set for single parameter functions. So that is why the tuple is needed.
Robert Maxton
@robertmaxton42
Feb 20 2017 15:39
right, I see. Unfortunate. Oh well.
Robert Maxton
@robertmaxton42
Feb 20 2017 18:28
can you pipe into a match statement somehow?
Yemi Bedu @ P&R
@pr-yemibedu
Feb 20 2017 18:29
a raw match? 1 |> (function | 1 -> true | _ -> false)
put this in fsi printfn "%A" (1 |> function | 1 -> true | _ -> false);;
then change the 1 to a 2 and try again.
Robert Maxton
@robertmaxton42
Feb 20 2017 18:47
mmkay
thanks