I'm aware of (||>) which does (a' * 'b) -> ('a -> b' -> 'c) -> 'c
But I've been finding this quite useful, and wondered if I was reinventing the wheel:
// ('a * 'a) -> ('a -> 'b) -> ('b * 'b)
let inline (|>>) (a,b) f = (f a, f b)
(*It can happen, I only discovered the ceil function half an hour ago!)
No, it doesn't.
However, you will encounter its variant very often if you use FParsec. Here is the type signature in FParsec documentation:
val (|>>): Parser<'a,'u> -> ('a -> 'b) -> Parser<'b,'u>
I think the library has a very well-designed set of operators which can be generalized for other purposes as well. The list of FParsec operators can be found here.
I did a bit of digging; |>> operator doesn't seem to have built-in Haskell counterpart although it is easy to be defined using Control.Arrow.
The operator you described is essentially the map function for a two-element tuple. The map function, in general has a signature (for some F<'a> which could be seq<'a> or many other types in F# libraries):
map : ('a -> 'b) -> F<'a> -> F<'b>
So, if you define F<'a> as a two element tuple, then your function is actually just map (if you flip the arguments):
type F<'a> = 'a * 'a
let map f (a, b) = (f a, f b)
The operation is not built-in anywhere in the F# library, but it is useful to realize that it actually matches a pattern that is quite common in F# libraries elsewhere (list, seq, array, etc.)
Looking at the Haskell answer referenced by #pad - in principle, Haskell makes it possible to define the same function for all types that support such operations using type classes (so you would write just fmap instead of Seq.map or instead of your TwoElementTuple.map, but it actually does not work for various technical reasons - so Haskellers need to call it differently).
In F#, this is not easily possible to define a single map function for different types, but you can still think of your function as a map for two-element tuples (even if you find it easier to give it a symbolic operator name, rather than the name map.)
Related
I'd like to convert tuple of two elements having the same type to a list. Code looks simple as this:
let toList (tuple: 'a * 'a): 'a list =
match tuple with
| (_ as fst, _ as snd) -> [fst; snd]
But somehow type of snd is 'a * 'a, so it seems like instead of binding second element of tuple to a variable the whole tuple is bound instead. Is it a bug in compiler or am I missing sth?
Actual code is more complicated, so the idea is not to rewrite the piece provided, but to understand what is wrong with the as usage here. I'd expect that as should go after the tuple to bound it as a whole, like this | (_ as fst, _ as snd) as tuple
For practical purposes #nilekirk's answer is better: you don't need as in this particular case at all.
But if you're wondering why snd has this type for learning purposes, here's an explanation.
Your pattern is compiled like this:
| ((_ as fst, _) as snd) ->
That is, tupling binds stronger than pattern aliasing.
If you want each as to apply to a single element of the tuple, you need to explicitly tell the compiler how to parenthesize them:
| ((_ as fst), (_ as snd)) ->
And incidentally, in F# tuples don't have to be in parens, so the outer parens are not necessary:
| (_ as fst), (_ as snd) ->
The correct syntactic form of the "as" pattern is
pat as ident
This defines ident to be equal to the pattern input and matches the pattern input
against pat.
For your code this means
let toList (tuple: 'a * 'a): 'a list =
match tuple with
| (fst, snd) -> [fst; snd]
where (fst, snd) is a tuple-pattern.
See F# language spec section 7.3 for full details of the "as" pattern.
Being relatively new to functional programming, I am still unfamiliar with all the standard operators. The fact that their definition is allowed to be arbitrary in many languages and also that such definitions aren't available in nearby source code, if at all, makes reading functional code unnecessarily challenging.
Presently, I don't know what <*> as it occurs in WebSharper.UI.Next documentation.
It would be good if there was a place that listed all the conventional definition for the various operators of the various functional languages.
I agree with you, it would be good to have a place where all implicit conventions for operators used in F# are listed.
The <*> operator comes from Haskell, it's an operator for Applicative Functors, its general signature is: Applicative'<('A -> 'B)> -> Applicative'<'A> -> Applicative'<'B> which is an illegal signature in .NET as higher kinds are not supported.
Anyway nothing stops you from defining the operator for a specific Applicative Functor, here's the typical definition for option types:
let (<*>) f x =
match (f, x) with
| Some f, Some x -> Some (f x)
| _ -> None
Here the type is inferred as:
val ( <*> ) : f:('a -> 'b) option -> x:'a option -> 'b option
which is equivalent to:
val ( <*> ) : f: option<('a -> 'b)> -> x: option<'a> -> option<'b>
The intuitive explanation is that it takes a function in a context and an argument for that function in the context, then it executes the function inside the context.
In our example for option types it can be used for applying a function to a result value of an operation which may return a None value:
let tryParse x =
match System.Int32.TryParse "100" with
| (true, x) -> Some x
| _ -> None
Some ((+) 10) <*> tryParse "100"
You can take advantage of currying and write:
Some (+) <*> tryParse "100" <*> Some 10
Which represents something like:
(+) (System.Int32.Parse "100") 10
but without throwing exceptions, that's why it is also said that Applicatives are used to model side-effects, specially in pure functional languages like Haskell. Here's another sample of option applicatives.
But for different types it has different uses, for lists it may be used to zip them as shown in this post.
In F# it's not defined because .NET type system would not make it possible to define it in a generic way however it would be possible using overloads and static member constraints as in FsControl otherwise you will have to select different instances by hand by opening specific modules, which is the approach used in FSharpx.
Just discovered elsewhere in the documentation on another subject...
let ( <*> ) f x = View.Apply f x
where type of View.Apply and therefore ( <*> ) is:
View<'A * 'B> -> View<'A> -> View<'B>
This one may be a stupid one but, having a look at (Eliminating my explicit state passing via like, monads and stuff)
type State<'s,'a> = State of ('s -> 'a * 's)
type StateBuilder<'s>() =
member x.Return v : State<'s,_> = State(fun s -> v,s)
member x.Bind(State v, f) : State<'s,_> =
State(fun s ->
let (a,s) = v s
let (State v') = f a
v' s)
let withState<'s> = StateBuilder<'s>()
let getState = State(fun s -> s,s)
let putState v = State(fun _ -> (),v)
let runState (State f) init = f init
what are the advantages of wrapping 's -> 'a * 's in State. Is it just a safety precaution?
I think it's more a matter of preference or convenience than safety; some people like to wrap the function in a single-case discriminated union type like that, and some don't.
I prefer not to wrap the functions, because it introduces a small amount of additional overhead and can inhibit the compiler from making some optimizations. In my ExtCore library, I've implemented the same thing, using a type alias instead of creating an actual type to wrap the function:
type StateFunc<'State, 'T> = 'State -> 'T * 'State
My guess is the wrapper comes from the Haskell tradition and languages that can generalize over monads.
In those laguanges you can have a generic >>= function but you can have only one implementatipon per type and sometimes there are more than one useful implementation.
This is the case of very generic types like 'a * 'b and 'a->'b.
For a function 'a -> 'b you can have a reader, a state or a parser monad defined, the way to tell which implementation pick up is to wrap them, so they have different types.
In F# things are different, most monad libraries don't define a generic >>= implementation since there is no clean way to do this in .NET, so there is no need to wrap the State since you will be explicitely applying a specific implementation of >>= and other monad related functions.
In absence of generic functions or overloads you can still wrap your State monad if you want, but then you'll have to wrap and unwrap code as in Haskell, in this case the decision depends on how much do you want to customize your types and that's a general question, not just with monads.
I'm brushing up on some key points in F# and my instructor has recommended a few exercises to help us grasp the concepts (not homework). He has given us certain types that the F# compiler would infer when given a sample expression, and we are supposed to be able to come up with an expressions that would provide it. The ones I have got somewhat stuck on are the following:
('a -> 'b) -> ('b -> 'c) -> ('a -> 'c)
and
('a -> 'b) * ('c -> 'a) -> ('c -> 'b)
The first one is of course the function composition operator (f o g)(x), or (>>), but I cannot think of anything that would have the second. Would anyone have any suggestions? Also, alternatives to the first one would be quite appreciated as well.
It looks like reverse composition (<<) and, as kvb pointed out, it needs be uncurried.
Is there a built-in "make pair" function or operator? I know this is trivial, but it would ease function composition in some cases.
Basically, just
let makePair a b = a, b
Can I also suggest Foogle?
No, I don't think there is a function like that in the F# library (and you also cannot treat , as an operator, which is allowed in Haskell).
F# lacks many other functions that are often used in function composition (or point-free style) including flip : ('a -> 'b) -> 'b -> 'a and curry : ('a * 'b -> c) -> 'a -> 'b - 'c). Frankly, I think that this is a good thing because it discourages people from writing code that is hard to read.
Of course, there are many cases where using some function like this would give readable code, but it is really difficult to find the right ballance.
FSharpx aims to fill some of those gaps (whenever possible). It has flip, curry and tuple constructors (among many other things).
If you're really interested in building Hoogle for F# you could work with Neil Mitchell (creator of Hoogle) to implement it.