I'm intrested because I would like to inspect the definitions of built-in functions in Prelude.
I searched for it, but only found the precompiled files in ~/.cabal/share/idris...
According to Vitus's comment I found the sources here:
https://github.com/idris-lang/Idris-dev/tree/master/libs
For smaller queries there is also :printdef in the REPL
Idris> :printdef uncurry
uncurry : (a -> b -> c) -> (a, b) -> c
uncurry f (a, b) = f a b
Related
I'm working in Cubical agda and trying to build up some common utilities for later proofs. One of these is that for any type A it is the 'same' as the type Σ A (\_ -> Top) where Top is the type with one element. And the issue is how to best expose this 'sameness' from the utility library. I can expose it as an equivalence, a path or an isomorphism, and maybe multiple ones.
I originally exposed it as just a path: top-path : Path A (Σ A (\_ -> Top)) which is built up using glue types from an underlying top-equiv : A ≃ Σ A (\_ -> Top). But when trying to use this in later proofs I found out that transporting along this path did not compute as I expected. My expectation was that it composed with fst to the identity, but in practice I found that it sometimes left in transp and prim^unglue terms. This was not the case if I used a particular concrete type for A, or if I used a similar construction using the equivalence.
Example:
-- Working
compute-top-path-Bool : (a : Bool) -> fst (transport (top-path Bool) a) == a
compute-top-path-Bool a = refl
compute-top-equiv-Any : (a : Bool) -> fst (transport-equiv (top-equiv Bool) a) == a
compute-top-equiv-Any a = refl
-- Broken
compute-top-path-Any : (a : A) -> fst (transport (top-path A) a) == a
compute-top-path-Any a = refl
--
-- Checking test (/Users/endobson/tmp/agda/test.agda).
-- /Users/endobson/tmp/agda/test.agda:104,26-30
-- transp (λ i → A) i0 (fst (prim^unglue a)) != a of type A
-- when checking that the expression refl has type
-- fst (transport (top-path A) a) == a
--
Self contained reproduction: https://gist.github.com/endobson/62605cfc15a92b9111391b459d03b548, and I'm using Agda version 2.6.1.3.
Thus my question is what is best solution for this problem? Am I somehow constructing my paths in a too complicated way and if I made them in a different way then the computational behavior would be better? Or is exposing the equivalence directly from my utility library expected? I find exposing the equivalence 'inelegant' as it seems that paths should be able to do this, but am not against doing so if they are known to be the better tool for this particular use case.
In the agda/cubical library we do tend to export the equivalence (or the iso) along with the path, because of issues like the one you mention.
The reason for those extra transp calls is that transport for Glue has to work in the general case where they might actually be required.
fst (prim^unglue a) should reduce away if you ask for the normal form though.
Ok, so I'm basically trying to add the bind operator to the option type and it seems that everything I try has some non-obvious caveat that prevent me from doing it. I suspect is has something to do with the limits of the .NET typesystem and is probably the same reason typeclasses can't be implemented in user code.
Anyways, I've attempted a couple of things.
First, I tried just the following
let (>>=) m f = ???
realizing that I want to do different things based on the type of m. F# doesn't allow overloads on function but .NET does allow them on methods, so attempt number two:
type Mon<'a> =
static member Bind(m : Option<'a>, f : ('a -> Option<'b>)) =
match m with
| None -> None
| Some x -> f x
static member Bind(m : List<'a>, f : ('a -> List<'b>)) =
List.map f m |> List.concat
let (>>=) m f = Mon.Bind(m, f)
No dice. Can't pick a unique overload based on previously given type info. Add type annotations.
I've tried making the operator inline but it still gives the same error.
Then I figured I could make the >>= operator a member of a type. I'm pretty sure this would work but I don't think I can hack it in on existing types. You can extend existing types with type Option<'a> with but you can't have operators as extensions.
That was my last attempt with this code:
type Option<'a> with
static member (>>=) (m : Option<'a>, f : ('a -> Option<'b>)) =
match m with
| None -> None
| Some x -> f x
"Extension members cannot provide operator overloads. Consider defining the operator as part of the type definition instead." Awesome.
Do I have any other option? I could define separate functions for different monads in separate modules but that sounds like hell if you want to use more than one version in the same file.
You can combine .NET overload resolution with inline/static constraints in order to get the desired behaviour.
Here's a step by step explanation and here's a small working example for your specific scenario:
type MonadBind = MonadBind with
static member (?<-) (MonadBind, m:Option<'a>, _:Option<'b>) =
fun (f:_->Option<'b>) ->
match m with
| None -> None
| Some x -> f x
static member (?<-) (MonadBind, m:List<'a>, _:List<'b>) =
fun (f:_->List<'b>) ->
List.map f m |> List.concat
let inline (>>=) m f : 'R = ( (?<-) MonadBind m Unchecked.defaultof<'R>) f
[2; 1] >>= (fun x -> [string x; string (x+2)]) // List<string> = ["2"; "4"; "1"; "3"]
Some 2 >>= (fun x -> Some (string x)) // Option<string> = Some "2"
You can also specify the constraints 'by hand', but when using operators they're inferred automatically.
A refinement of this technique (without the operators) is what we use in FsControl to define Monad, Functor, Arrow and other abstractions.
Also note you can use directly Option.bind and List.collect for both bind definitions.
Why do you need to (re-define) "bind"? For starters, Option.bind is already defined.
You can use it for defining a "computational expression builder" (F# name for monadic "do" syntax sugar).
See previous answer.
This is my code in C#
Observable.Zip(ob1, ob2, (a, b) => a + b);
I am trying to convert this to F# using Pipe-Forwarding operator
ob1 |> Observable.Zip(ob2, Func<_,_,_> (fun a b -> a + b))
It won't compile because it can't get which overload I am trying to use.
Any clue ?
The following works just fine, I am just curious if I could make the pipe-forwarding operator work here. Technically it should take ob1 on left hand side as first parameter and take the two supplied parameters as 2nd and 3rd right ?
Observable.Zip (ob1,ob2 ,Func<_,_,_>(fun a b -> a + b))
As mentioned in the comment you can implement a simple wrapper like this:
open System.Reactive.Linq
let zipWith (f : 'T -> 'U -> 'R)
(second: IObservable<'U>)
(first: IObservable<'T>)
: IObservable<'R> =
Observable.Zip(first, second, f)
and with this just do as you wanted:
ob1 |> zipWith (fun a b -> a+b) ob2
PS: it looks even nicer if you do it like this:
ob1 |> zipWith (+) ob2
You seem to have some wrong impressions of how pipe operator works, so I'll try to clear those up.
Let's make things simpler to type out and say we have functions foo and bar:
let foo (a, b, f) = f a b
let bar a b f = f a b
foo has more or less the same shape as Observable.Zip and takes a tuple as an argument (this is how C# functions are seen in F#), bar is the same but is curried.
This works:
foo (ob1, ob2, fun a b -> a + b)
bar ob1 ob2 (fun a b -> a + b)
This doesn't work:
ob1 |> bar ob2 (fun a b -> a + b)
That's because what pipe operator does, is taking the value on the left, and passing it as the last argument to the function on the right. You'd need bar to be defined like this:
let bar b f a = f a b
That's why the functions in for example the List module are defined in a way that the actual list is passed in as the last argument - that makes pipelining work in a nice way.
This also doesn't work:
ob1 |> foo (ob2, fun a b -> a + b)
Apart from the previous problem, it would also require pipe operator to look inside a tuple and attach a value there, and that's really not how it works. A tuple is a single value in F#. The function that would work for that example would be this one:
let foo (b, f) a = f a b
But clearly that's not what we want.
You can still use Observable.Zip in a pipeline fashion like this:
ob1 |> fun x -> Observable.Zip(x, ob2, Func<_,_,_> (fun a b -> a + b))
Or simply go with the wrapper the other answer suggests.
Given a string of digits, I would like to have a sequence of tuples mapping the non-zero characters with their position in the string. Example:
IN: "000140201"
OUT: { (3, '1'); (4, '4'); (6, '2'); (8, '1') }
Solution:
let tuples = source
|> Seq.mapi (fun i -> fun c -> (i, c))
|> Seq.filter (snd >> (<>) '0')
It seems like (fun i -> fun c -> (i, c)) is a lot more typing than it should be for such a simple and presumably common operation. It's easy to declare the necessary function:
let makeTuple a b = (a, b)
let tuples2 = source
|> Seq.mapi makeTuple
|> Seq.filter (snd >> (<>) '0')
But it seems to me that if the library provides the snd function, it should also provide the makeTuple function (and probably with a shorter name), or at least it should be relatively easy to compose. I couldn't find it; am I missing something? I tried to build something with the framework's Tuple.Create, but I couldn't figure out how to get anything other than the single-argument overload.
But it seems to me that if the library provides the snd function, it should also provide the makeTuple function.
F# assumes that you decompose tuples (using fst, snd) much more often than composing them. Functional library design often follows minimal principle. Just provide functions for common use cases, other functions should be easy to define.
I couldn't find it; am I missing something?
No, you aren't. It's the same reason that FSharpPlus has defined tuple2, tuple3, etc. Here are utility functions straight from Operators:
/// Creates a pair
let inline tuple2 a b = a,b
/// Creates a 3-tuple
let inline tuple3 a b c = a,b,c
/// Creates a 4-tuple
let inline tuple4 a b c d = a,b,c,d
/// Creates a 5-tuple
let inline tuple5 a b c d e = a,b,c,d,e
/// Creates a 6-tuple
let inline tuple6 a b c d e f = a,b,c,d,e,f
I tried to build something with the framework's Tuple.Create, but I couldn't figure out how to get anything other than the single-argument overload.
F# compiler hides properties of System.Tuple<'T1, 'T2> to enforce pattern matching idiom on tuples. See Extension methods for F# tuples for more details.
That said, point-free style is not always recommended in F#. If you like point-free, you have to do a bit of heavy lifting yourself.
The #pad's answer is great, just to add my 2 cents: I am using similar operator
let inline (-&-) a b = (a, b)
and it looks very convenient to write let x = a -&- b
Maybe you'll find this operator useful too
It's not a practically important issue, but I'd like to see an example of tacit programming in F# where my point-free functions can have multiple arguments (not in form of a list or tuple).
And secondly, how such functions can manipulate a complex data structure. I'm trying it out in F# Interactive, but have no success yet.
I tried, for instance:
> (fun _ -> (fun _ -> (+))) 333 222 111 555
Is that right way?
And:
> (fun _ -> (fun _ -> (+))) "a" "b" "c" "d";;
val it : string = "cd"
F# doesn't contain some of the basic functions that are available in Haskell (mainly because F# programmers usually prefer the explicit style of programming and use pointfree style only in the most obvious cases, where it doesn't hurt readability).
However you can define a few basic combinators like this:
// turns curried function into non-curried function and back
let curry f (a, b) = f a b
let uncurry f a b = f (a, b)
// applies the function to the first/second element of a tuple
let first f (a, b) = (f a, b)
let second f (a, b) = (a, f b)
Now you can implement the function to add lengths of two strings using combinators as follows:
let addLengths =
uncurry (( (first String.length) >> (second String.length) ) >> (curry (+)))
This constructs two functions that apply String.length to first/second element of a tuple, then composes them and then adds the elements of the tuple using +. The whole thing is wrapped in uncurry, so you get a function of type string -> string -> int.
In F#, the arity of functions is fixed, so you're not going to be able to write both
(op) 1 2
and
(op) 1 2 3 4
for any given operator op. You will need to use a list or other data structure if that's what you want. If you're just trying to avoid named variables, you can always do "1 + 2 + 3 + 4". The most idiomatic way to add a list of numbers in F# is List.sum [1;2;3;4], which also avoids variables.