fsprojects / FSharpPlus

Extensions for F#
https://fsprojects.github.io/FSharpPlus
Apache License 2.0
847 stars 94 forks source link

Examples for the Haskell compability #66

Closed ShalokShalom closed 6 years ago

ShalokShalom commented 6 years ago

Currently, there is no example in the tutorial for the compatibility with Haskell.

wallymathieu commented 6 years ago

There are the following samples:

wallymathieu commented 6 years ago

So perhaps having links to these files would help?

ShalokShalom commented 6 years ago

Yep.

gusty commented 6 years ago

By pure causality, yesterday I almost copy the sample files to the docs for the Haskell Compatibility. In the end I decided that I would want to review the code and that will take me some time (which yesterday I didn't had). So let's discuss a bit how to organize this samples in the docs.

As I said yesterday in another discussion, I see an overlap between the samples and the docs, since the docs also contain sample and my guess is that we should move all the samples to the doc. Again this is not just copy-paste, it will require adding some explanations to the sample code.

ShalokShalom commented 6 years ago

By pure causality, I almost suggested to actually copy the sample files and was then concerned that this is too much code for this overview. IMHO, a more generic and simple example is suitable.

wallymathieu commented 6 years ago
Operation F#+ / F# F#+ Haskell Compatibility Haskell
List.append @   ++
  <<   .
  <| $ $
  = == ==
  <> =/ =/
flip />   />
apply function to value </  or  |>   </
       
Functor      
map <!> or <<|   <$> or fmap
same as map but arguments interchanged |>>    
       
Monoid      
monoid zero element getZero() mempty mempty
append ++ or plus mappend mappend
       
Applicative functors      
apply (combine) <*>   <*>
Sequence actions, discarding the value of the first argument. *>   *>
Sequence actions, discarding the value of the second argument. <*   <*
A variant of <*> with the arguments reversed. <**>   <**>
Lift a value. result   pure
       
Alternative      
alternatives: binary operation <|>   <|>
       
Monad      
Bind Sequentially compose two actions, passing any value produced by the first as an argument to the second. >>=   >>=
Same as >>=, but with the arguments interchanged. =<<   =<<
wallymathieu commented 6 years ago

?

wallymathieu commented 6 years ago

Then we could perhaps write what can and cannot be done in f# compared to Haskell

gusty commented 6 years ago

@wallymathieu @ShalokShalom feel free to send a PR regarding this, whoever takes the initiative (including myself) just send a message first to avoid duplicate efforts.

My feeling is that we should add that table and regarding the sample files there are actually two files. One is too short, the other one is too long.

The long one, is in the Samples From FsControl folder, which at the same time came from an old exploratory project, originally in google code but now it's being imported to github by some devs, see this import and also this other import, with the translation table used at that time.

Now regarding the Learn you a Haskell file, that was an exercise @vstastny did to learn about the typeclassy stuff here, following the original haskell tutorial, and he gently contributed back to this repo. But note that it's not using the Haskell compatibility, because the idea I think, was to apply the same concepts in F#. So I think it worths adding to the doc, but maybe not in the compatibility (although it might be linked). One thing is syntax and another is abstractions.

ShalokShalom commented 6 years ago

I adore this table.

Then we could perhaps write what can and cannot be done in f# compared to Haskell

Yes, absolutely.

wallymathieu commented 6 years ago

The easiest way to get the table into the docs could be to use github wiki ? Then we could start collaborate on it as well.

wallymathieu commented 6 years ago

Since it does not contain any code examples, it's perhaps not so much a good fit for literate style of programming with fsx, or what's your thougts @gusty ?

gusty commented 6 years ago

The easiest way to get the table into the docs could be to use github wiki ?

I don't get it, what's complicated? You can put it directly in the docs, they support markdown directly AFAIK.

wallymathieu commented 6 years ago

It doesn't support the same markdown syntax. It's a minor thing: you need to transform the table to the dialect of markdown that fsharp formatting supports.

gusty commented 6 years ago

Shame, but moving that out of the docs for a technical limitation seems hacky, Is there any other way? Something like linking to an external site, as I did for the PlantUML diagram?

gusty commented 6 years ago

It's a minor thing: you need to transform the table to the dialect of markdown that fsharp formatting supports.

Actually this might be the easiest solution. What do you think?

wallymathieu commented 6 years ago

Indeed.

wallymathieu commented 6 years ago

The question is mostly what kind of markdown tables fsharp formatting supports?

gusty commented 6 years ago

https://github.com/fsprojects/FSharp.Formatting/issues/7 and see the linked examples.

wallymathieu commented 6 years ago

Nice!

ShalokShalom commented 6 years ago

Very nice to see, that something such (comparable) trivial gets immediately implemented, while the whole range of the .NET world is still in chaos for such things: https://github.com/dotnet/docs/issues/3446

wallymathieu commented 6 years ago

https://gist.github.com/wallymathieu/19c74f784652f18ae3111056b8403f82

wallymathieu commented 6 years ago

So perhaps someone wants to do a small pull request :wink:

gusty commented 6 years ago

Cool ! I found some inaccuracies, here's the corrected version

Also I noticed some issues.

ShalokShalom commented 6 years ago

OK, i did some changes to this, lets see how they appeal you:

https://gist.github.com/ShalokShalom/11cf9b1943d36ac51939e83bb0fced84

ShalokShalom commented 6 years ago

Some questions:

wallymathieu commented 6 years ago

I've started using <| sort of the same way I use it in Haskell. Since I'm not very deep into it, it's kind of helpful to have something where it's explained.

gusty commented 6 years ago

Not all operators are representable in F#, we can create issues, but the right place to create them will be in the F# compiler project, because there's nothing we can do about it here.

Regarding $ it's a bit for completeness there, but actually the main purpose of the operator which is to avoid parens, it's defeated since it doesn't have the same associativity as in Haskell. Again, there's nothing we can do about it.

Some operators still seem to be unnamed yet: What is the purpose?

Which one, for example?

I've started using <| sort of the s ...

Yes, I use it from time to time, but it also has not the same associativity, so for piping expressions it doesn't work, it's better to do the F# way, I mean reverse the pipe and write with the |> in those cases.

wallymathieu commented 6 years ago

Mmm, indeed. What is your thoughts about the Ocaml way of doing things? More module oriented instead of type class oriented.

gusty commented 6 years ago

I don't have any experience in OCaml, but it seems to be more module oriented. AFAIK they use their "functor" feature, which is not the same as the functor abstraction, it's rather a parametrizable module and they don't have typeclasses, but I read somewhere that both techniques are equivalent.

ShalokShalom commented 6 years ago

OCaml is very module oriented since they allow higher-order polymorphism by higher-order modules and yes, you can implement type classes as such ones.

Ah, I got now that I can use <| in order to substitute the $ in Standard F-Sharp.

Which one, for example?

=, <| and <> are without description currently and apply function to a value is without operators.

If there are no equivalents on one side or the other, can we mention it by something like not available Otherwise is it questionable, if the list is either incomplete or the operator missing.

Some other questions:

pure' is correct? Since I do not find it in the source code.

And if binary operation is available in both F-Sharp and Haskell, why implement one in F-Sharp Plus? Do they work differently?

wallymathieu commented 6 years ago

https://github.com/gusty/FSharpPlus/blob/master/src/FSharpPlus/Compatibility.fs#L94

ShalokShalom commented 6 years ago

Oh, then Github's search does probably crash with `

Thanks a lot

wallymathieu commented 6 years ago

apply function to a value </ or |> has gotten dropped

ShalokShalom commented 6 years ago

So we can remove it?

ShalokShalom commented 6 years ago

Or mention not available

wallymathieu commented 6 years ago

It's very common in f# code, so if it's not available in Haskell then I would find it useful have that fact in the table.

wallymathieu commented 6 years ago

I don't remember why I added </ for Haskell.

ShalokShalom commented 6 years ago

See now: https://gist.github.com/ShalokShalom/11cf9b1943d36ac51939e83bb0fced84

So, how can I see the specific result of this table? How does it look like in real life? Since I like to adjust the visual appearance.

I hope its fine, that I actually named this project?

F#+ Haskell Compatibility burst the width of the column, so I think this can make it leaner and also give the project some identity. :)

gusty commented 6 years ago

apply function to a value </ or |> has gotten dropped

Yes, the definitions are 3 rows above.

And if binary operation is available in both F-Sharp and Haskell, why implement one in F-Sharp Plus?

Do they work differently? Not 100% sure what do you mean. Regarding to <|> it's simply the same operator in Haskell and FSharpPlus and also in other languages, like purescript, Idris if I'm not wrong.

I don't remember why I added </ for Haskell.

That's confusing, probably it was added by me in the original project. The thing is that in Haskell you can partially apply an operator on both sides, well I found out that by using those operators you achieve more or less the same effect but at the cost of ending up with combination of operators. Here's an example:

let f x = fun n -> n - x

in Haskell you can write it:

let f x = (- x)

here you can write:

let f x = (-)/> x

But in fact the idea of these operators is to be able to transform a function in an operator:

let sum x y = x + y

let a = x </sum/> y
gusty commented 6 years ago

@ShalokShalom you can start adding it to the docs, then after running Build or just building the docs you'll see how FSharp Formatting renders that table.

ShalokShalom commented 6 years ago

Oh, I see. I thought initially, this table is just to point out the compatibility layer itself. So, in that case, a huge load of operators is missing? What will we include and what not?

ShalokShalom commented 6 years ago

But in fact the idea of these operators is to be able to transform a function in an operator:

let sum x y = x + y

let a = x </sum/> y

I think we should point this out on its own. Otherwise, the whole sense would get gone.

gusty commented 6 years ago

Definitely.

gusty commented 6 years ago

What should get included and what not?

I would say, let's get it done with the basic stuff, as we have it for example. The goal of the Haskell compatibility module is to facilitate translating code from Haskell, including running on-off examples, but normally if you translate something that later will become more important we should remove the Haskell compatibility. A good example of this, is the recent @wallymathieu work with Validations, see for example that inflexion point happening here

ShalokShalom commented 6 years ago

if you translate something that later will become more important we should remove the Haskell compatibility

So, a Haskell compatibility source-to-source converter onto F-Sharp would be reasonable?

To do this automaticly?

gusty commented 6 years ago

It will never be possible to fully emulate Haskell, specially because of the lazyness and the different type system. Still, my experience is that Haskell.Compatibility helps to run Haskell examples or to do the initial steps to port code coming from Haskell.

Still, human touch will always be required.

ShalokShalom commented 6 years ago

I mean Haskell Compatibility into native F-Sharp (Plus)

gusty commented 6 years ago

Oh, I see what you mean. I guess it makes sense, at least what we can do is to provide a brief guideline of what are the steps to take, and which decisions have to be made.

ShalokShalom commented 6 years ago

Yes, since this seems to be a simple find-and-replace, this might be a nice project for me as a newbie. :)