In Haskell, some Functor fmap
fmap :: (a -> b) -> f a -> f b
In TypeScript,
type F<A> = A[];
const F = // type constructor
<A>(a: A): F<A> => [a];
type map = <A, B> // function => function
(f: (a: A) => B) =>
(Fa: F<A>) => F<B>;
Similarly, in Dart, I try to implement
typedef F<A> = Map<String, A>;
typedef Fmap<A, B> = (F<B> Function(F<A>)) (Function(B Function(A)));
but the second line has errors, what would be the correct syntax?
To be honest I have not the slightest idea what you are trying to do, since I don't get any of the two examples, but this compiles fine:
typedef F<A> = Map<String, A>;
typedef Fmap<A, B> = F<B> Function(F<A>) Function(B Function(A));
Related
I have this code:
Ok stringBuffer {
let r = get some list....
match r with
| [] -> "no active tasks"
| r -> String.Join("\n", r)
}
with stringBuffer defined as:
[<AutoOpen>]
module StringBuffer =
type StringBuffer = StringBuilder -> unit
type StringBufferBuilder () =
member inline this.Yield (txt: string) = fun (b: StringBuilder) -> Printf.bprintf b "%s" txt
member inline this.Yield (c: char) = fun (b: StringBuilder) -> Printf.bprintf b "%c" c
member inline this.Yield (strings: #seq<string>) = fun (b: StringBuilder) -> for s in strings do Printf.bprintf b "%s\n" s
member inline this.YieldFrom (f: StringBuffer) = f
member this.Combine (f, g) = fun (b: StringBuilder) -> f b; g b
member this.Delay f = fun (b: StringBuilder) -> (f()) b
member this.Zero () = ignore
member this.For (xs: 'a seq, f: 'a -> StringBuffer) =
fun (b: StringBuilder) ->
use e = xs.GetEnumerator ()
while e.MoveNext() do
(f e.Current) b
member this.While (p: unit -> bool, f: StringBuffer) =
fun (b: StringBuilder) -> while p () do f b
member this.Run (f: StringBuffer) =
let b = StringBuilder()
do f b
b.ToString()
let stringBuffer = StringBufferBuilder()
type StringBufferBuilder with
member inline this.Yield (b: byte) = fun (sb: StringBuilder) -> Printf.bprintf sb "%02x " b
I am not the author of the StringBuffer module. I'm using it regularly as it makes using StringBuilder super convenient to use in F#
I can mix strings and logic easily:
stringBuffer {
"hello"
if x = 3 then "world"
}
but, in the example at the beginning of this post, I am getting the following compilation error:
[FS0708] This control construct may only be used if the computation expression builder defines a 'Zero' method.
In the computation expression, the Zero method is defined as ignore so the problem is probably there. But my question is:
What is this error about? why does this specific use case require the implementation of the Zero method?
My understanding is that the Zero method is used if the expression would return nothing, as it is not valid for a computation expression; But since I specify a string, why would this execution path return nothing?
Edit:
Screenshot of the error (Rider / dotnet 5)
Now, the error is reduced to this scenario:
Ok stringBuffer {
let r = get some list....
match r with
| [] -> "no active tasks"
| r -> String.Join("\n", r)
}
trigger the error, but
let s =
stringBuffer {
let r = get some list....
match r with
| [] -> "no active tasks"
| r -> String.Join("\n", r)
}
Ok s
does not
It works for me if I add parens:
let result =
Ok (stringBuffer {
let r = [1;2;3]
match r with
| [] -> "no active tasks"
| r -> String.Join("\n", r)
})
printfn "%A" result
Without the parens, the "Zero" error message occurs because function application is left-associative, so the compiler thinks you mean something like this: (Ok stringBuffer) { "str" }. Since Ok stringBuffer is an expression that lacks a Zero member, this does not compile.
Amusingly, if you define your own Ok operator that returns a valid builder, it will compile fine:
let Ok (sb : StringBufferBuilder) = sb
let result = Ok stringBuffer { "hello "; "world" } // produces: "hello world"
I want to extend some system types and later use them via inlining
type System.String with
member this.foo n = this + "!" + n
type System.Boolean with
member this.foo n = sprintf "%A!%A" this n
Now I call these extension methods
let x = "foo".foo "bar"
let y = true.foo "bar"
which gives me this
- val x : System.String = "foobar"
- val y : string = "true!"bar""
All fine and dandy - but now I want to wrap the call to .foo into an inline function
let inline foo n v = (^T : (member foo : ^N -> ^S) v, n)
let z = foo "bar" "baz"
Only now I get a compiler error telling me that
> The type 'string' does not support the operator 'foo':
well ... it does!
Can somebody explain whats going on?
Extension methods are not taken into account in static member constraints (possible duplicate of this) and this is a general problem when you want to implement generic code using member constraints and make it work also with already defined or primitive types.
See the user voice request, also the workarounds mentioned here and Don Syme's explanation of why it's complicated to implement it in the F# compiler.
If you follow the links there you will see currently the way to workaround it basically involves creating an intermediate type and overloads for all the known types and a generic one for the extensions.
This is a very basic example of how to workaround it:
type Foo = Foo with
static member ($) (Foo, this:int) = fun (n:int) -> this + n
static member ($) (Foo, this:string) = fun n -> this + "!" + n
static member ($) (Foo, this:bool) = fun n -> sprintf "%A!%A" this n
let inline foo this n = (Foo $ this) n
//Now you can create your own types with its implementation of ($) Foo.
type MyType() =
static member ($) (Foo, this) =
fun n -> printfn "You called foo on MyType with n = %A" n; MyType()
let x = foo "hello" "world"
let y = foo true "world"
let z = foo (MyType()) "world"
You can enhance it by adding an explicit generic overload for new types:
// define the extensions
type System.String with
member this.foo n = this + "!" + n
type System.Boolean with
member this.foo n = sprintf "%A!%A" this n
// Once finished with the extensions put them in a class
// where the first overload should be the generic version.
type Foo = Foo with
static member inline ($) (Foo, this) = fun n -> (^T : (member foo : ^N -> ^S) this, n)
static member ($) (Foo, this:string) = fun n -> this.foo n
static member ($) (Foo, this:bool) = fun n -> this.foo n
// Add other overloads
static member ($) (Foo, this:int) = fun n -> this + n
let inline foo this n = (Foo $ this) n
//later you can define any type with foo
type MyType() =
member this.foo n = printfn "You called foo on MyType with n = %A" n; MyType()
// and everything will work
let x = foo "hello" "world"
let y = foo true "world"
let z = foo (MyType()) "world"
You can further refine it by writing the static constraints by hand and using a member instead of an operator (see an example here),
At the end of the day you will end up with something like this generic append function from FsControl.
Statically resolved type constraints do not support extension methods. It's just not a feature of F#.
If you would like F# to gain support for higher-kinded polymorphism, you can vote for it on user voice.
I have written a Haskell-style Functor type class:
Class Functor (f: Type -> Type) := {
map {a b: Type}: (a -> b) -> (f a -> f b);
map_id: forall (a: Type) (x: f a), map id x = x
}
Where id has the obvious definition.
Now, I've proven instances of Functor for list and the function type. But I want to prove statements about any functor. To start with, I want to prove what's essentially a tautology: a restatement of the map_id for any functor.
Theorem map_id_restatement: forall (F: Type -> Type),
Functor F -> forall T (x: F T), map id x = x.
The idea being to prove this theorem I would simply apply map_id. But I get an error when I try to start proving this:
Toplevel input, characters 88-91:
Error:
Could not find an instance for "Functor F" in environment:
F : Type -> Type
T : Type
x : F T
But the Functor F instance should be already in scope due to the assumption in the type. Why is it not recognized?
Edit:
OK, I figured out I could make it work by quantifying the Functor F:
Theorem map_id_restatement: forall (F: Type -> Type) (finst: Functor F),
forall T (x: F T), map id x = x.
Proof. apply #map_id. Qed.
Why is this necessary? Interestingly, it doesn't work if I don't explicitly give a name to the functor instance (i.e. if I just write (_: Functor F)).
I don't know whether this is a bug or not, but notice that when you write something like Functor F -> SomeType, you are implicitly saying that SomeType does not depend on the Functor instance, which is not true in your case: the full type of your theorem, printing all implicit arguments, would be something like:
Theorem map_id_restatement: forall (F: Type -> Type) (finst: Functor F),
forall T (x: F T), #map F fints T T (#id T) x = x.
If you replace finst by _, you get
Theorem map_id_restatement: forall (F: Type -> Type) (_: Functor F),
forall T (x: F T), #map F _ T T (#id T) x = x.
which can't really be type-checked, since _ is not really a variable name.
Notice that, if you bind Functor F anonymously before the colon, Coq accepts it:
Theorem map_id_restatement (F: Type -> Type) (_ : Functor F) :
forall T (x: F T), map (#id T) x = x.
Proof. apply #map_id. Qed.
Presumably, here Coq is treating the _ in a different way, and replacing it by an automatically generated name, instead of actually leaving it unnamed. You can also use the following form, which works both under the forall or before the colon:
Theorem map_id_restatement (F: Type -> Type) : forall `(Functor F),
forall T (x: F T), map (#id T) x = x.
Proof. apply #map_id. Qed.
I am working on a parser combinator library and found some behavior I couldn't explain. The first time I run the combinator it runs significantly slower than the second time that I run it. I repo'd the behavior with this small app (running Release with optimizations on)
let (>>=) first callback state =
let reply = first state
callback reply state
let time f =
let start = System.DateTime.Now
f()
printfn "%s" ((System.DateTime.Now - start).ToString())
[<EntryPoint>]
let main args =
let x1 state = "foo"
let compound =
x1 >>= fun i ->
x1 >>= fun j ->
x1 >>= fun a ->
x1 >>= fun b ->
x1 >>= fun c ->
x1 >>= fun d ->
x1 >>= fun e ->
x1 >>= fun f ->
x1 >>= fun j ->
fun _ -> [i;j;a;b;c;d;e;f]
time (fun () -> compound "a" |> ignore)
time (fun () -> compound "b" |> ignore)
time (fun () -> compound "c" |> ignore)
0
Running this output I get
00:00:00.0090009
00:00:00.0010001
00:00:00
Why is the first iteration so much slower than the second or third?
Edit, so I tried this out in C# as well. It runs faster, but the results are similar.
using System;
namespace fssharp
{
public delegate string Parser(string state);
public delegate Parser Callback(string result);
public class Combinator
{
public static Parser Combine(Parser p, Callback callback)
{
Parser r = state =>
{
var result = p(state);
return callback(result)(state);
};
return r;
}
public static string X1(string state)
{
return "foo";
}
}
class Program
{
static void Main(string[] args)
{
Parser comb = state =>
Combinator.Combine(Combinator.X1, result =>
Combinator.Combine(Combinator.X1, result2 =>
Combinator.Combine(Combinator.X1, result3 =>
Combinator.Combine(Combinator.X1, result4 =>
Combinator.Combine(Combinator.X1, result5 =>
Combinator.Combine(Combinator.X1, result6 =>
Combinator.Combine(Combinator.X1, result7 =>
Combinator.Combine(Combinator.X1, result8 =>
Combinator.Combine(Combinator.X1, result9 => s => result + result2 + result3 +result4 +result5 +result6 +result7+result8+result9)))
))))))(state);
var now = DateTime.Now;
comb("foo");
Console.WriteLine(DateTime.Now - now);
now = DateTime.Now;
comb("foo2");
Console.WriteLine(DateTime.Now - now);
}
}
}
This prints out
00:00:00.0030003
00:00:00
I'm now curious why C# is faster here
Even tough I can't tell for sure, it is either:
JIT: The function is JIT'ed the first time it runs, and then it uses the already compiled version
It detects that the same function is called with the same parameters and cache the result.
Try to call it with a different parameter. If the time stays the same it's 2, if time is different it's 1
I really hate asking this kind of question but I'm at the end of my wits here. I am writing an incremental parser but for some reason, just cannot figure out how to implement functor instance for it. Here's the code dump:
Input Data Type
Input is data type yielded by parser to the coroutine. It contains the current list of input chars being operated on by coroutine and end of line condition
data Input a = S [a] Bool deriving (Show)
instance Functor Input where
fmap g (S as x) = S (g <$> as) x
Output Data Type
Output is data type yielded by coroutine to Parser. It is either a Failed message, Done [b], or Partial ([a] -> Output a b), where [a] is the current buffer passed back to the parser
data Output a b = Fail String | Done [b] | Partial ([a] -> Output a b)
instance Functor (Output a) where
fmap _ (Fail s) = Fail s
fmap g (Done bs) = Done $ g <$> bs
fmap g (Partial f) = Partial $ \as -> g <$> f as
The Parser
The parser takes [a] and yields a buffer [a] to coroutine, which yields back Output a b
data ParserI a b = PP { runPi :: [a] -> (Input a -> Output a b) -> Output a b }
Functor Implementation
It seems like all I have to do is fmap the function g onto the coroutine, like follows:
instance Functor (ParserI a) where
fmap g p = PP $ \as k -> runPi p as (\xs -> fmap g $ k xs)
But it does not type check:
Couldn't match type `a1' with `b'
`a1' is a rigid type variable bound by
the type signature for
fmap :: (a1 -> b) -> ParserI a a1 -> ParserI a b
at Tests.hs:723:9
`b' is a rigid type variable bound by
the type signature for
fmap :: (a1 -> b) -> ParserI a a1 -> ParserI a b
at Tests.hs:723:9
Expected type: ParserI a b
Actual type: ParserI a a1
As Philip JF declared, it's not possible to have an instance Functor (ParserI a). The proof goes by variance of functors—any (mathematical) functor must, for each of its arguments, be either covariant or contravariant. Normal Haskell Functors are always covariant which is why
fmap :: (a -> b) -> (f a -> f b)`
Haskell Contravariant functors have the similar
contramap :: (b -> a) -> (f a -> f b)`
In your case, the b index in ParserI a b would have to be both covariant and contravariant. The quick way of figuring this out is to relate covariant positions to + and contravariant to - and build from some basic rules.
Covariant positions are function results, contravariant are function inputs. So a type mapping like type Func1 a b c = (a, b) -> c has a ~ -, b ~ -, and c ~ +. If you have functions in output positions, you multiply all of the argument variances by +1. If you have functions in input positions you multiply all the variances by -1. Thus
type Func2 a b c = a -> (b -> c)
has the same variances as Func1 but
type Func3 a b c = (a -> b) -> c
has a ~ 1, b ~ -1, and c ~ 1. Using these rules you can pretty quickly see that Output has variances like Output - + and then ParserI uses Output in both negative and positive positions, thus it can't be a straight up Functor.
But there are generalizations like Contravariant. The particular generalization of interest is Profunctor (or Difunctors which you see sometimes) which goes like so
class Profunctor f where
promap :: (a' -> a) -> (b -> b') -> (f a b -> f a' b')
the quintessential example of which being (->)
instance Profunctor (->) where
promap f g orig = g . orig . f
i.e. it "extends" the function both after (like a usual Functor) and before. Profunctors f are thus always mathematical functors of arity 2 with variance signature f - +.
So, by generalizing your ParserI slightly, letting there be an extra parameter to split the ouput types in half, we can make it a Profunctor.
data ParserIC a b b' = PP { runPi :: [a] -> (Input a -> Output a b) -> Output a b' }
instance Profunctor (ParserIC a) where
promap before after (PP pi) =
PP $ \as k -> fmap after $ pi as (fmap before . k)
and then you can wrap it up
type ParserI a b = ParserIC a b b
and provide a slightly less convenient mapping function over b
mapPi :: (c -> b) -> (b -> c) -> ParserI a b -> ParserI a c
mapPi = promap
which really drives home the burden of having the variances go both ways---you need to have bidirectional maps!