Giter VIP home page Giter VIP logo

fsharpplus's Introduction

FSharpPlus

Download NuGet NuGet Preview Made with F# License - Apache 2.0

F#+ is a base library that aims to take F# to the next level of functional programming.

What if we imagine F# as more than it is?

F#+ builds upon FSharp, using generic programming techniques to help you avoid boiler plate code. However, by naming conventions and signatures it can be seen to 'enhance' rather than 'replace' existing patterns as much as possible.

Getting started is easy since you can start with enjoying some of the extensions and generic functions, but you will find other parts of F#+ unfold before you and become useful the deeper in you get.

See the documentation for more details.

Seeking Help

We're happy to help with any questions, including complete beginners!

Please do join us to chat on:

...or you can ask a question on stack overflow with tag F#+

Contribute

The project is hosted on GitHub where you can report issues, fork the project and submit pull requests. Opening issues for discussion or asking questions is welcome, don't hesitate to fill the New Issue form!

  • The Developer Guide contains details about idioms of implementation in terms of how the type class concept translates in the implementation.
  • The Design Guidelines contains details about design choices guiding the implementation with regard to naming, and choices impacting runtime and compile time performance.

fsharpplus's People

Contributors

adz avatar atifaziz avatar cannorin avatar choc13 avatar cmdq avatar cmeeren avatar dogwith1eye avatar fcallejon avatar forki avatar gdennie avatar gdziadkiewicz avatar gitter-badger avatar gusty avatar happypig375 avatar jannesiera avatar laenas avatar mausch avatar nickdarvey avatar paullucas avatar pnobre avatar pzelmanski avatar rneatherway avatar rodriguestiago0 avatar shalokshalom avatar shmew avatar smoothdeveloper avatar swoorup avatar vstastny avatar wallymathieu avatar wasphub avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

fsharpplus's Issues

Inverse of ToSeq/ToList

Description

Is there a function that is the inverse of toList?

for Example NonEmptyList<'a> can be easily transformed into 'a list. What would be the name of the inverse function and is there an overloaded static member for that available?

`>>=` tends to throw bizarre error in mono

This library is really cool! Thank you for all the hard work.

I'm not sure if this library claims to support mono or not. But I'm getting a strange error whenever I use the >>= and =<< operators. Surprisingly this error occurs even if I annotate types.

The error is:

FSC: error FS0192: internal error: GenUnionRef m

Use the new Result type instead of Choice for Errors

We'll need to adjust to what would be the new standard for signaling errors.

The question is what do we do with the existing type Choice<'OK,'Error>.

I think we should keep if as much as possible for backwards compatibility, but not just between this library version, there might be a lot of source code that uses the Choice convention and needs to keep working without doing a big refactoring.

Travis build failing

It seems that it's failing in the latest commits with this message:

Generating '/home/travis/build/gusty/FSharpPlus/docsrc/tools/../content/abstraction-foldable.html'
No output has been received in the last 10m0s, this potentially indicates a stalled build or something wrong with the build itself.
Check the details on how to adjust your build configuration on: https://docs.travis-ci.com/user/common-build-problems/#Build-times-out-because-no-output-was-received

But there's nothing wrong with the build, it works locally and it also succeed in MyGet.

Rename empty and append

The idea is to re-organize one more time these kind of functions.

The current situation is that we have only two sets of these monoid-like functions:

  • Monoids: empty and append
  • Alternative: mzero and mplus (or <|>)

It's good to have F# names like empty and append but the question now is do they really belong to Monoids? Wouldn't be better to move them to Alternative?

If we do so, we'll keep F# names, and empty will coincide with Haskell and other languages in which it defines the identity for Alternative.

Another problem with the current situation is that we have mzero and mplus which in fact are commonly used for MonadPlus, not Alternative, although this library doesn't make the distinction, the abstraction really correspond to Alternative, since it's more generic than MonadPlus.

But it's nice to have monoids with F# names, for lists, arrays, nothing would change since their Monoid implementation is the same as the Alternative.

Moreover, since Monoid basic operations have no default definition, we can use the Alternative as a default definition for Monoids which are also Applicatives.

All sounds very nice, but then it comes the open question, which names should we consider then for Monoid operations?

One alternative is to go back to Haskell-like names like memptyand mappend. I don't like that m. Sometimes it means monad, sometimes monoid? Confusing.

Better names would be zero and plus (without the m) since Monoid is a mathematical concept, but we have also, zero and plus in our Numerics, which btw needs some redesign too (yes, I'm suggesting we may unify them).

So, let's treat these redesign as a separate issue, I would say first rename them back to memptyand mappend then we can close this issue and discuss further redesign.

Computation Expressions

This is kind of a follow-up of this issue in FsControl.

Despite the fact that now both project are merged, F#+ never had a clear way to approach Computation Expressions, it all started with a basic do-notation from an experimental project trying to emulate some Haskell features.

Then a monadPlus builder was incorporated in order to be able to encode Monoidal Monads and also a linq builder, to allow to create generic linq queries, similar to C# linq capabilities but with all extra F# stuff. All these efforts were directed towards having a more F#-ish abstraction instead of a simple Haskell do-notation.

However this initial effort seems to be leading us to a dead-end, now I'm convinced that this should be approached in a different way, instead of providing different builders with different number of operations, provide a set of complete builders, each one serving different kind of monads.

There is an interesting example of a maybe builder in the Computation Expression Zoo paper:

let x = maybe { 
    let a, b = 5, 0
    if b = 0 then return! None 
    printfn "Calculating..."
    return (a / b) }

This will fail with a divide by zero exception with the current design which uses always a delayed computation expression.

After experimenting a bit, revisiting the paper about the Computation Expression Zoo and other libraries, I came up with what I think might be an interesting set of cages for the beasts of this zoo.

On one axis we have the type of builders: Delayed and Non-delayed and on another axis we have Monoidal Monads and Sequencing Monads, so this leave us with 4 cages:

  • Delayed - MonadPlus: seq falls in this cage.
  • Delayed - Sequencial: most other delayed monads falls in this cage, like async.
  • Strict - MonadPlus: list and array are typical examples.
  • Strict - Sequencial: option falls normally here but since it's also a MonadPlus it can also be enclosed in the above cage.

So the goal is to provide the client of this library a simple mechanism to:

  • Get the better default cage for the animal.
  • Allow him to switch to a different cage, typical example would be when treating option as either a MonadPlus or a Sequencing Monad.

An additional bonus would be to consider Monad Transformers which may have a different Bind which does a lift as described in the paper with the AsyncSeq example which roughly corresponds to the SeqT<Async<'t>> Monad Transformer.

I think the zoo is huge but at the same time there is a lot of boiler plate code in each case mentioned on that paper and leaving all the choices to the library designer as suggested there, leads the end-user of the library with a 'magic' builder with not very clear semantics and a lot of resposability to the designer , who should decide over different valid approaches (google for the many ways to implement the maybe builder in F#).

Finally, the end-user has always the choice to create his custom builder in the unlikely case this abstraction doesn't suit his need.

In short I think there is a great value in providing set of complete generic builders as an alternative to create them from scratch and also as an alternative to use a library which provides a custom one.

Slow compiler performance in Monad Transformers sample with Visual Studio, and can't give hints.

When I try Monad Tranformers sample with Visual Studio 2015 along with F# PowerTools, I noticed that the CPU peaks when IDE sits idle, probably due to type inference engine and syntax colorization is delayed for few seconds.

I am not sure if this issue is related to F# compiler , VisualFSharp or FSharpPlus. Can you suggest me any workarounds like putting a hint to make IDE happy for better performance ?
Also when I explicitly give type like below:

let getValidPassword : ErrorT<Async<_>> =
monad {
    let! s = liftAsync getLine
    if isValid s then return s
    else return! throw -1
}
</ catch /> (fun s -> throw ("The error was: " + decodeError s))

Notice Error<Async<_>>

`I get errors like below :

  • Could not resolve the ambiguity inherent in the use of the operator 'Bind' at or near this program point. Consider using type annotations to resolve the ambiguity.
  • Could not resolve the ambiguity inherent in the use of the operator 'LiftAsync' at or near this program point. Consider using type annotations to resolve the ambiguity.
  • Type constraint mismatch when applying the default type 'obj' for a type inference variable. No overloads match for method 'LiftAsync'. The available overloads are shown below (or in the Error List window). Consider adding further type constraints

Why is that so ?

Assembly version issue

HI, after having downloaded FSharpPlus NuGet package of version 0.0.3
with dependency to FsControl (>= 1.0.8), using

let _11_r9 = (+) <!> (Some 3) <*> (Some 5)

in my project is without any problem.

This, however (using ZipList)

let _11_r15 = (+) <!> (ZipList <| seq { 1..3 } ) <*> (ZipList <| Seq.init 3 (fun _ -> 100))

gets compiled with the following message

No way to resolve conflict between "FSharp.Core, Version=4.3.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" and "FSharp.Core, Version=4.3.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a". Choosing "FSharp.Core, Version=4.3.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" arbitrarily.
Consider app.config remapping of assembly "FSharp.Core, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" from Version "4.3.0.0" [C:\Program Files (x86)\Reference Assemblies\Microsoft\FSharp\3.0\Runtime\v4.0\FSharp.Core.dll] to Version "4.3.1.0" [] to solve conflict and get rid of warning.
C:\Windows\Microsoft.NET\Framework\v4.0.30319\Microsoft.Common.targets(1605,5): warning MSB3247: Found conflicts between different versions of the same dependent assembly.

When run, the program crashes with the following

{"Could not load file or assembly 'FSharp.Core, Version=4.3.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. The system cannot find the file specified.":"FSharp.Core, Version=4.3.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"}

This issue can be somehow solved by adding this line into App.config

<bindingRedirect oldVersion="4.3.1.0" newVersion="4.3.0.0"/>

Cheers
Vladimir

Add Append and Plus for Result

At the moment Result is not Alternative nor Monoid.

There are many issues with this.

  • Zero and Empty are not always representable.
    In option we have None, but here which is the Zero for Result? It should be Error ? where ? means in fact no results yet.

  • For Plus and Append there multiple valid instances:
    I'm tempted to add instances consistent with the existing for option. This means "the first good" for Append and "the semigroup of all goods" for Plus, but here there are many possible options for the last case, I mean then Plus between two Errors: take the first, take the second or take both and require that error is a Semigroup.

The last sentence reminds me #51 it seems to me that one can argue that error types should be semigroup, to be able to collect validation errors or inner errors.
Strings are semigroups but concatenation of error messages without separators is not a good idea. Maybe there is a way to find a monoid for Exceptions.

Use struct Tuples

  • New overloads for struct tuples can be added.
  • They can also be used internally since they offer better performance in some scenarios.

In principle it looks like it won't be a breaking change.

Namespaces

Given the current (mature) state of the library, it's time to think about the namespaces.

We have currently:

  • FSharpPlus which auto-opens Operators

    • Data: contains all F#+ types, including Monoids, Monads, Collections.

    • Operators contains mostly generic functions and operators that are being added on top of standard F# operators functions, without redefinitions. It also contains some modules:

      • Arrows: defines additional arrow related operators by shadowing bit operators.
      • Applicative Math: although it's in a separated module, these operators don't conflict with anything
      • Generic Math: redefines some very basic math operators, by opening this module you enter in a Generic math mode, it's easier to write generic math functions but some interactions with .net functions with funny semantics for math operators and also units of measures become restricted.
    • Lens: contains not just Lens, it also comes with Prism, Traversals, Iso. I think Optics is being used to encompass all these abstractions. An issue here is that set is a redefinition of an F# keyword. I was thinking renaming it, maybe to burn which is the way you cloud write something through a lens in the physical world.

    • Compatibility: At the moment it contains only Haskell, but more modules could be added later for toehr languages (purescript for example). This seems to make sense to me.

  • FsControl contains all (typeclassy) Abstractions, we inherited this namespace from FsControl but we can rename it to either FSharpPlus.Control or FSharpPlus.Invokables, any other suggestion?

Any thoughts?

Conseable types

Is there a standard static member for types that are Conseable?
In principle anything that can be mapped to a List or Seq could be conseable. No?

Validation like Either but with an accumulating Applicative

Hi!

I would like to use FSharpPlus to get a Validation data type like
https://hackage.haskell.org/package/Validation

@gusty Would you mind giving me some guidance to implement basic Validation using Applicative Functor + NonEmptyList with FSharpPlus?

Notes:

  1. In the long term I would like to use that in Xamarin.Android
  2. I've also seen http://fsprojects.github.io/FSharpx.Extras/reference/fsharpx-validation.html, but seems to receive less attention from maintainers. Current versions are not able to target Xamarin.Android :(

Build Script Errors when compiling on Mono

I'm running into few build script errors in the build.fsx file when compiling on Mono version 4.6.2

Extra quote at end of build.fsx

bash-3.2$ sudo ./build.fsx
build.fsx(76,42): error FS0514: End of file in string begun at or before here

Which is easily fixed by removing the extraneous quote at the end of the file

exec fakeExe ("makefile.fsx"::passedArgs)"
------------------------------------------^

TypeInitializationException in applyExecutionPermissionUnix

let applyExecutionPermissionUnix path =
    let _,stat = Syscall.lstat(path)
    Syscall.chmod(path, FilePermissions.S_IXUSR ||| stat.st_mode) |> ignore

System.TypeInitializationException: The type initializer for 'Mono.Unix.Native.Syscall' threw an exception

Commenting out the applyExecutionPermissionUnix function lets me build fine, which makes me wonder whether it's really a necessary step.

Traversing infinite sequences

From @mausch on April 16, 2014 21:23

Traversing an infinite list works fine in Haskell: http://ideone.com/GuytMd
But the equivalent F# + FSharpPlus code doesn't terminate and eats infinite memory:

let x = traverse (fun x -> if x > 4 then Some x else None) (Seq.initInfinite id)

This is probably because foldr is currently strict for seq

Maybe a specialized foldr would work here, e.g. http://fpish.net/blog/anton.tayanovskyy/id/1453/http~3a~2f~2fwww.intellifactory.com~2fblogs~2fanton.tayanovskyy~2f2009~2f12~2f11~2fFoldr-or-FoldBack-on-Infinite-F~21sharp~21-Sequences.article

(BTW this stackoverflow question made me realize this).

Copied from original issue: gusty/FsControl#26

Warnings about F# metadata node

Description

When compiling a project that references FSharpPlus I get the warning

unknown(1,1): warning FS3186: An error occurred while reading the F# metadata node at position 878 in table 'ivals' of assembly 'FsControl.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'. The node had no matching declaration. Please report this warning. You may need to recompile the F# assembly you are using.

Repro steps

Add FSharpPlus to solution
Build

Expected behavior

No warnings

Actual behavior

Warnings

Please provide a description of any known workarounds.

Related information

  • Windows 10
  • Nuget installed

_

Sorry, this issue is just my mistake.

Roadmap to 1.0

I think it's time to draft a roadmap for a stable 1.0 version.

I have always the impression that we're close, but we keep changing stuff in the library.

This is not intended to be a wish list of feature but a list of what are the coming breaking changes we have ahead.

Does anybody wan't to compile a list?

Hint the issues marked as RFCs are all good candidates for the list.

Examples for monad transformers

It would be great if there were some examples on how to compose/use monad transformers in a bit more depth.

something like

let fn : ErrorT<Reader<int,int>> = 
            monad{
                   let! x1 = lift ask
                   let! x2 = Choice1of2 1
                   return ((+) x1 x2)
            }

ErrorT.run fn //not sure about this.

Though I'm still beginning F# and this doesn't compile (and I'm not sure why).
The attempt was to have some sort of errorable computation that reads from the environment

F# Intellisense

Hi,

I have downloaded and trying to use latest FSharpPlus (VS2013 Premium Update 4, F# 3.1), but Intellisense seems to go crazy with the scripts like "Learn You a Haskell.fsx"..

I copied the text from this script into .fs file. Intellisense initially processes the file for 10-15 mins consuming CPU and memory, but then crashed with error "Assembly reference FsControl.Core.dll was not found or invalid". The file FsControl.Core.dll exists in the folder and is valid.

Sounds like a glitch in the VS / F# software.

Did you experience this? If yes, any workarounds?

Thanks,
Pavel.

Compose

Add the type Compose to be able to compose applicative functors.

Review/reform toString and tryParse

The difference between toString and (the F# built-in) string may be subtle.

I think toString function can play together with tryParse in order to get a sort of mini-serializer for simple F# values.

A rule can be enforced, for parse / tryParse: toString >> parse = id.

As a consequence, toString for a string will add the double quotes and tryParse will expect them.

The same way tryParse has a fallback mechanism, toString (or another function can be created) can fallback to the generic string function. The idea behind this is that toString is free of any rule as long as there is no correspondent tryParse defined for that type.

Here are some examples:

toString "abc"
> val it : string = ""abc""

toString ["a"; "b"; "c"]
> val it : string = "[a; b; c]"

toString (set ["a"; "b"; "c"])
> val it : string = "set [a; b; c]"

tryParse<string> "abc"
> val it : string option = None

tryParse<string> ""abc""
> val it : string option = Some "abc"

Here's a relevant discussion in Haskell for their read / show functions

Another thing is to consider renaming these functions: toString might be confused with .NET ToString instance member and parse / tryParse when using any parser library.

Also, if we decide to keep toString, parse (or maybe tryParse) should be fromString. If we think from the point of view of serializer this makes more sense, but the term string doesn't add any information about the format, it should rather be something like toFSharpString and fromFSharpString or shortened as toFsString / fromFsString.

Finally we can consider keeping the parse / tryParse functions and implement a fromFsString that returns a Result type, with a detailed parsing error description .... and possibly keep the parse / tryParse functions aligned with the Parse .NET methods, which means language agnostic (?) and no rules at all.

Many open questions.

Please drop your thoughts, specially @mausch who implemented initially the ToString abstraction. Keep in mind consistency is a high premise of this library.

Add a Lazy List

It would be nice to have a Lazy List implementation here.
Apart of the interesting abstraction it provides for users of this library, it might be useful to use it as underlying type to implement some seq traversals, which require lot of cons operations.

One possibility is to import the implementation from the old PowerPack.

NonEmptyList map gives me :: Seq<'b>

given a NonEmptyList<'a> and running that thru FSharpPlus.Operators.map I am getting a Seq<'b> where as I expected it to return a NonEmptyList<'b>. What am I doing wrong?
Only when I fully qualify the call to map like

NonEmptyList.map transform someNonEmptyList

the result is the correct type of functor

Feedback - using F#+

@wallymathieu I wonder if you're using the library for some projects, prototyping or just playing with the exotic typeclassy features?

I'm just curious and at the same time I would like to know if there's any stuff you would like to see added to this lib.

Review extension methods.

From @gusty on November 5, 2015 12:47

By adding a few attributes we add the possibility to use some methods from C# and F#.
However in order to use them:

  • From C# the method should not be generic. Also there is a problem if the method accepts an f# function, it will be tedious to use it.
  • From F# the method should not have dummy arguments, though this is not a technical limitation, they can be used but add lot of noise.

Another issue is than when the containing namespace is opened you see many methods, some of them will not work in C# but it displays everything. I think that's really annoying but an alternative is to remove the extension attribute of the generic methods.

Perhaps extension methods belong to a different project, F# extension methods are already being defined in F#+ so for C# we can create a C#+ project and put them there, adapting the function arguments, there will be a lot of boilerplate code in that project but to the outside world will be clean.

Copied from original issue: gusty/FsControl#55

Remove "App.config" from .NET Core build

Description

Now even if my project is pure netstandard2.0 after installing 1.0.0-CI00148 build it got App.config included by Paket with all that redirects stuff, that I'm sure not needed at all there.

Related information

  • Operating system Windows 10 Pro
  • .NET SDK :
.NET Command Line Tools (2.1.300-preview1-008174)

Product Information:
 Version:            2.1.300-preview1-008174
 Commit SHA-1 hash:  b8df89a54f

Runtime Environment:
 OS Name:     Windows
 OS Version:  10.0.15063
 OS Platform: Windows
 RID:         win10-x64
 Base Path:   C:\Program Files\dotnet\sdk\2.1.300-preview1-008174\

Microsoft .NET Core Shared Framework Host

  Version  : 2.1.0-preview1-26216-03
  Build    : f2c3216183d20416568a4bbf5bb7d153e826f153

Bind for Expr<'T> (Quotation Monad)

After a short but interesting discussion with @eiriktsarpalis I thought it might be interesting to add a Bind implementation for Expr<'t> which allows to combine functions returning quotations.

One open question is how the quotation will be evaluated, however I did a draft some years ago which uses the splice operator to signify that there is an evaluation at that point, together with a runUntyped function which accepts any quotation evaluator and makes sure all splices are evaluated properly.

It might be worth adding a specific implementation of quotation evaluator to this library, but it has to be very efficient. At the moment I wrote that code there were no efficient implementations around.

Applicative operators

This decision is in the roadmap to 1.0

We currently have applicative operators which are very convenient to write "formula with effects":

let x = Some 4 |+| Some 6

let y = 4 +| tryParse "6"

We can extend this to many other operators, not just basic math:

|=|
|>|
|<|

But when using them with pure values they will become:

|=
|> ops, this is the forward pipe
<| ... and this one the backwards

and if we add logic operators:

|&&|
|||| .. this looks weird.

Maybe we can rename them to:

.+.
.-.
.>.
.=.
.||.

Any thoughts?

Unify/throw away lmap and rmap

I will start quoting what many bloggers states about Profunctors:

A Profunctor is just a bifunctor that is contravariant in the first argument and covariant in the second.

So, if I have a type that is both a Contravariant and a Functor (covariant) at the same time, that type is a Profunctor where rmap is map and lmap is contramap.

If so, do we need that duplication?

In principle looks like we can safely throw away the LMap and RMap invokables, then we can define lmap and rmap as aliases of contramap and map respectively.

Or we can go even further and throw away lmap and rmap.

Also we can shorten contramapto cmap as they did in Purescript.

Finally (this might be a separate issue but let's include it here) we can argue the same for Bifunctor's second and map.

Any thoughts?

Design notes

After using F#+ and designing types implementing the required static member we observe that types end up with undesired duplication of signature, for example:

ZipList.map f x (function) and ZipList.Map(x, f) (static member).

This can be solved by "hiding" the static member by marking it as "deprecated", but I was thinking that if we use the applicative operator for map we solve that issue and on top of that this code:

(+) <!> ZipList [1;2] <*> ZipList [3;4]

Will just work, independently of F#+ generic calls. I mean even if FSharpPlus namespace is not open and generic operators are not in scope, the above code will compile, without resolving any complicated static constraint.

So, I propose the following design guideline:

  • For unary operations, like ToSeq, OfBytes we use lower case. The exception here is Return which is a keyword in lowercase.

  • For binary:

    1. Is there any standard/wide accepted operator ( <!>, <|>, >>=, =>>, <*> ...) ? => Use it.
    2. Does it make sense tupled => Use it tupled, lowercase.
    3. Define it Uppercase but in the client code is recommended to use an attribute to hide it.
  • For ternary operations or more: 2) and 3) above applies.

All this leads one more time to the question about the utility of the Extensions attributes.
I addition, now we've seen many operators need internal tupling of arguments in order to avoid upcasting to interfaces at overload resolution, which render those attributes unusable.

For C# usability we may consider instead the extensions defined in Extensions.fs file.

We will still have duplicated members/functions internally, but this is fine because it allows us to expose the non-generic function and simplifies the implementation of the static member, which is desirable, I mean to keep the body of the static member short (a call to the non generic).

Use [<struct>] attribute for DUs

When this project started that was not a possibility, but now in F# 4.1 we can mark DUs as structs and we have many DUs, specially single case (Reader, Cont, ZipList, ... )

At the moment the only value type DU we're using is the recently added Result from FSharp.Core but we should consider adding some more.

I'm looking for a comprehensive guide and recommendations regarding this decision, many of our DU's encapsulates functions, which means that in the end references will be used, some others are more likely to use values, eg NonEmptyList.

This decision is key to stabilize this library, because changing afterwards will break binary compatibility.

Make Sum the default Monoid for Numeric types

This is something I have more than one year trying to find a good reason why not to do it.

First some background, at the moment there is no Monoid implementation for numeric types.
This comes from the old original design, copied from Haskell.

The reason why in Haskell there is no instance is because there are two equally valid instances for Monoid: (+) and (*).

But this reason doesn't sound good enough for me:

  • In real-world code situations (+) is used at least 95% of the time, currently to fold a monoid we have to map the wrapper, apply concat and map the unwrapper.
  • In .NET string also supports the (+) operation and string is already a Monoid with that operation
  • If I'm not wrong, in Scalaz they already adopted it as a default.
  • Even in Haskell I don't agree 100% with that design decision, there are many cases there where there is more than one valid instance, but in most cases they decided over one as the default while the others need to wrap. Examples are Maybe for MonadPlus, List for Functor and Applicative to name some of them.

Drawback of doing this:

Since there is no loss of functionality the drawback is that we stop forcing the user to be explicit, I can only think of a situation when accidentally someone folded with (+) although if it did not compile I doubt the error message will be helpful.

Any thoughts?

length None = 0

Description

I just realized (via runtime err) that legth None = 0.
So my question is why is that? It makes sense on the one hand that something none existing is 0 but then ...

F# 4.1 compiler raises warnings

I created a new console project in VS 2017 RC, add FSharpPlus NuGet dependency into it, copied the follwing code into it:

open FSharpPlus

[<EntryPoint>]
let main argv = 
    let lst11n21n12n22 = 
        monad {                
            let! x1 = [1;   2]
            let! x2 = [10; 20]
            return ((+) x1 x2)}
    
    let neLst11n21n12n22 = 
        monad {                
            let! x1 = { NonEmptyList.Head =  1; Tail =  [2] }
            let! x2 = { NonEmptyList.Head = 10; Tail = [20] }
            return ((+) x1 x2)}
    
    let some14 = 
        monad {                
            let! x1 = Some 4
            let! x2 = Some 10
            return ((+) x1 x2)}
    0

and try to compile. It's compiled successfully, but with some strangely looking warnings:

1>------ Rebuild All started: Project: FSharpPlusTest, Configuration: Debug Any CPU ------
1> C:\Program Files (x86)\Microsoft SDKs\F#\4.1\Framework\v4.0\fsc.exe -o:obj\Debug\FSharpPlusTest.exe
1>-g
1>--debug:full
1>--noframework
1>--define:DEBUG
1>--define:TRACE
1>--doc:bin\Debug\FSharpPlusTest.XML
1>--optimize-
1>--tailcalls-
1>--platform:anycpu32bitpreferred
1>-r:D:\github\FSharpPlusTest\packages\FsControl.1.0.9\lib\net40\FsControl.Core.dll
1>-r:C:\Program Files (x86)\Reference Assemblies\Microsoft\FSharp.NETFramework\v4.0\4.4.0.0\FSharp.Core.dll
1>-r:D:\github\FSharpPlusTest\packages\FSharpPlus.0.0.4\lib\net40\FSharpPlus.dll
1>-r:C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework.NETFramework\v4.6.1\mscorlib.dll
1>-r:C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework.NETFramework\v4.6.1\System.Core.dll
1>-r:C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework.NETFramework\v4.6.1\System.dll
1>-r:C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework.NETFramework\v4.6.1\System.Numerics.dll
1>--target:exe
1>--warn:3
1>--warnaserror:76
1>--vserrors
1>--utf8output
1>--fullpaths
1>--flaterrors
1>--subsystemversion:6.00
1>--highentropyva+
1>C:\temp.NETFramework,Version=v4.6.1.AssemblyAttributes.fs
1>AssemblyInfo.fs
1>Program.fs
1>
1>FSC: warning FS3186: An error occurred while reading the F# metadata node at position 878 in table 'ivals' of assembly 'FsControl.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'. The node had no matching declaration. Please report this warning. You may need to recompile the F# assembly you are using.
1>FSC: warning FS3186: An error occurred while reading the F# metadata node at position 879 in table 'ivals' of assembly 'FsControl.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'. The node had no matching declaration. Please report this warning. You may need to recompile the F# assembly you are using.
1>FSC: warning FS3186: An error occurred while reading the F# metadata node at position 880 in table 'ivals' of assembly 'FsControl.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'. The node had no matching declaration. Please report this warning. You may need to recompile the F# assembly you are using.
1>FSC: warning FS3186: An error occurred while reading the F# metadata node at position 881 in table 'ivals' of assembly 'FsControl.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'. The node had no matching declaration. Please report this warning. You may need to recompile the F# assembly you are using.
1>FSC: warning FS3186: An error occurred while reading the F# metadata node at position 1118 in table 'ivals' of assembly 'FsControl.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'. The node had no matching declaration. Please report this warning. You may need to recompile the F# assembly you are using.
1>FSC: warning FS3186: An error occurred while reading the F# metadata node at position 1141 in table 'ivals' of assembly 'FsControl.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'. The node had no matching declaration. Please report this warning. You may need to recompile the F# assembly you are using.
1>FSC: warning FS3186: An error occurred while reading the F# metadata node at position 1164 in table 'ivals' of assembly 'FsControl.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'. The node had no matching declaration. Please report this warning. You may need to recompile the F# assembly you are using.
1>FSC: warning FS3186: An error occurred while reading the F# metadata node at position 1256 in table 'ivals' of assembly 'FsControl.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'. The node had no matching declaration. Please report this warning. You may need to recompile the F# assembly you are using.
1> FSharpPlusTest -> D:\github\FSharpPlusTest\FSharpPlusTest\bin\Debug\FSharpPlusTest.exe
========== Rebuild All: 1 succeeded, 0 failed, 0 skipped ==========

netcore support

Hello, is there any plan to support .net core? Is there any roadmap for this repo?

Btw, nice library.

Generic put doesn't work in Monad Transformers

The following code doesn't compile:

let initialState = -1
let x = put initialState : ListT<State<int, unit list>>
let y = put initialState : ErrorT<State<int, Choice<unit,string>>>

UPDATE

After the re-re introduction of liftM it compiles again, but it could generate more efficient code using map.

Test scripts

It would be nice to have in the build process a step to compile all scripts from the samples and the doc.
Some scripts are very sensitive to changes and fail to compile after an unnoticed breaking change.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.