Type kind error when creating instance of Functor typeclass - typeclass

I'm trying to implement Functor typeclass instance for a very trivial type Foo:
data Foo a = Foo a
instance functorFoo :: Functor (Foo a) where
map fn (Foo a) = Foo (fn a)
Purescript gives me not-so-helpful error message:
Could not match kind
Type -> Type
with kind
Type
What does it mean? I'm not yet really familiar with the Kind-system.

But I'd still like to find out why does the first version not work. Like how does the Functor typeclass differ from e.g. Semigroup where the first version worked just fine.
Let's look at the definition of the Functor type class:
class Functor f where
map :: forall a b. (a -> b) -> f a -> f b
It contains f a and f b types in the type signature of map which clearly indicates that f is of kind Type -> Type (it "carries" another type). On the other hand Semigroup clearly relates to plain types of kind Type:
class Semigroup a where
append :: a -> a -> a
So Semigroup is a class which can be defined for plain types like String, Int, List a, Map k v or even a function a -> b (which can also be written as (->) a b) but not type constructors which require another type like List Map k (->) a (I have to use this notation here).
On the other hand Functor class requires type constructors so you can have instances like Functor List, Functor (Map k) or Functor ((->) a).

I found a solution. Instead of defining it as:
instance functorFoo :: Functor (Foo a) where
I need to define it as:
instance functorFoo :: Functor Foo where
But I'd still like to find out why does the first version not work. Like how does the Functor typeclass differ from e.g. Semigroup where the first version worked just fine.

Related

Why does F# require type placeholders for ToDictionary?

given
[
1,"test2"
3,"test"
]
|> dict
// turn it into keyvaluepair sequence
|> Seq.map id
|> fun x -> x.ToDictionary<_,_,_>((fun x -> x.Key), fun x -> x.Value)
which fails to compile if I don't explicitly use the <_,_,_> after ToDictionary.
Intellisense works just fine, but compilation fails with the error: Lookup on object of indeterminate type based on information prior to this program point
So, it seems, Intellisense knows how to resolve the method call.
This seems to be a clue
|> fun x -> x.ToDictionary<_,_>((fun x -> x.Key), fun x -> x.Value)
fails with
Type constraint mismatch.
The type 'b -> 'c is not compatible with type IEqualityComparer<'a>
The type 'b -> 'c' is not compatible with the type 'IEqualityComparer<'a>'
(using external F# compiler)
x.ToDictionary((fun x -> x.Key), id)
works as expected as does
let vMap (item:KeyValuePair<_,_>) = item.Value
x.ToDictionary((fun x -> x.Key), vMap)
I've replicated the behavior in FSI and LinqPad.
As a big fan of and avid reader of Eric Lippert I really want to know
what overload resolution, (or possibly extension methods from different places) are conflicting here that the compiler is confused by?
Even though the types are known ahead, the compiler's getting confused between the overload which takes an element selector and a comparer. The lambda compiles to FSharpFunc rather than the standard delegate types in C# like Action or Func, and issues do come up translating from one to the other. To make it work, you can :
Supply a type annotation for the offending Func
fun x -> x.ToDictionary((fun pair -> pair.Key), (fun (pair : KeyValuePair<_, _>) -> pair.Value)) //compiles
or name the argument as a hint
fun x -> x.ToDictionary((fun pair -> pair.Key), elementSelector = (fun (pair) -> pair.Value))
or force it to pick the 3 argument version:
x.ToLookup((fun pair -> pair.Key), (fun (pair) -> pair.Value), EqualityComparer.Default)
Aside
In your example,
let vMap (item:KeyValuePair<_,_>) = item.Value
x.ToDictionary((fun x -> x.Key), vMap)
you would explicitly need to annotate vMap because the compiler cannot find out what type the property exists on without another pass. For example,
List.map (fun x -> x.Length) ["one"; "two"] // this fails to compile
This is one of the reasons why the pipe operator is so useful, because it allows you to avoid type annotations:
["one"; "two"] |> List.map (fun x -> x.Length) // works
List.map (fun (x:string) -> x.Length) ["one"; "two"] //also works
The short answer:
The extension method ToDictionary is defined like this:
static member ToDictionary<'TSource,_,_>(source,_,_)
but is called like this:
source.ToDictionary<'TSource,_,_>(_,_)
The long answer:
This is the F# type signature of the function you are calling from msdn.
static member ToDictionary<'TSource, 'TKey, 'TElement> :
source:IEnumerable<'TSource> *
keySelector:Func<'TSource, 'TKey> *
elementSelector:Func<'TSource, 'TElement> -> Dictionary<'TKey, 'TElement>
But I only specified two regular parameters: keySelector and elementSelector. How come this has a source parameter?!
The source parameter is actually not put in the parenthesis, but is passed in by saying x.ToDictionary, where x is the source parameter. This is actually an example of a type extension. These kinds of methods are very natural in a functional programming language like F#, but more uncommon in an object oriented language like C#, so if you're coming from the C# world, it will be pretty confusing. Anyway, if we look at the C# header, it is a little easier to understand what is going on:
public static Dictionary<TKey, TElement> ToDictionary<TSource, TKey, TElement>(
this IEnumerable<TSource> source,
Func<TSource, TKey> keySelector,
Func<TSource, TElement> elementSelector
)
So the method is defined with a "this" prefix on a first parameter even though it is technically static. It basically allows you to add methods to already defined classes without re-compiling or extending them. This is called prototyping. It's kinda rare if you're a C# programmer, but languages like python and javascript force you to be aware of this. Take this example from https://docs.python.org/3/tutorial/classes.html:
class Dog:
tricks = [] # mistaken use of a class variable
def __init__(self, name):
self.name = name
def add_trick(self, trick):
self.tricks.append(trick)
>>> d = Dog('Fido')
>>> e = Dog('Buddy')
>>> d.add_trick('roll over')
>>> e.add_trick('play dead')
>>> d.tricks # unexpectedly shared by all dogs
['roll over', 'play dead']
The method add_trick is defined with self as a first parameter, but the function is called as d.add_trick('roll over'). F# actually does this naturally as well, but in a way that mimics the way the function is called. When you declare:
member x.doSomething() = ...
or
member this.doSomething() = ...
Here, you are adding function doSomething to the prototype (or class definition) of "x"/"this". Thus, in your example, you actually have three type parameters, and three regular parameters, but one of them is not used in the call. All you have left is to declare the key selector function, and the element selector function, which you did. That's why it looks weird.

What is the typical definition/meaning of this F# operator <*>

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>

constrain generic type to inherit a generic type in f#

let mapTuple f (a,b) = (f a, f b)
I'm trying to create a function that applies a function f to both items in a tuple and returns the result as a tuple. F# type inference says that mapTuple returns a 'b*'b tuple. It also assumes that a and b are of the same type.
I want to be able to pass two different types as parameters. You would think that wouldn't work because they both have to be passed as parameters to f. So I thought if they inherited from the same base class, it might work.
Here is a less generic function for what I am trying to accomplish.
let mapTuple (f:Map<_,_> -> Map<'a,'b>) (a:Map<int,double>,b:Map<double, int>) = (f a, f b)
However, it gives a type mismatch error.
How do I do it? Is what I am trying to accomplish even possible in F#?
Gustavo is mostly right; what you're asking for requires higher-rank types. However,
.NET (and by extension F#) does support (an encoding of) higher-rank types.
Even in Haskell, which supports a "nice" way of expressing such types (once you've enabled the right extension), they wouldn't be inferred for your example.
Digging into point 2 may be valuable: given map f a b = (f a, f b), why doesn't Haskell infer a more general type than map :: (t1 -> t) -> t1 -> t1 -> (t, t)? The reason is that once you include higher-rank types, it's not typically possible to infer a single "most general" type for a given expression. Indeed, there are many possible higher-rank signatures for map given its simple definition above:
map :: (forall t. t -> t) -> x -> y -> (x, y)
map :: (forall t. t -> z) -> x -> y -> (z, z)
map :: (forall t. t -> [t]) -> x -> y -> ([x], [y])
(plus infinitely many more). But note that these are all incompatible with each other (none is more general than another). Given the first one you can call map id 1 'c', given the second one you can call map (\_ -> 1) 1 'c', and given the third one you can call map (\x -> [x]) 1 'c', but those arguments are only valid with each of those types, not with the other ones.
So even in Haskell you need to specify the particular polymorphic signature you want to use - this may be a bit of a surprise if you're coming from a more dynamic language. In Haskell, this is relatively clean (the syntax is what I've used above). However, in F# you'll have to jump through an additional hoop: there's no clean syntax for a "forall" type, so you'll have to create an additional nominal type instead. For example, to encode the first type above in F# I'd write something like this:
type Mapping = abstract Apply : 'a -> 'a
let map (m:Mapping) (a, b) = m.Apply a, m.Apply b
let x, y = map { new Mapping with member this.Apply x = x } (1, "test")
Note that in contrast to Gustavo's suggestion, you can define the first argument to map as an expression (rather than forcing it to be a member of some separate type). On the other hand, there's clearly a lot more boilerplate than would be ideal...
This problem has to do with rank-n types which are supported in Haskell (through extensions) but not in .NET type system.
One way I found to workaround this limitation is to pass a type with a single method instead of a function and then define an inline map function with static constraints, for example let's suppose I have some generic functions: toString and toOption and I want to be able to map them to a tuple of different types:
type ToString = ToString with static member inline ($) (ToString, x) = string x
type ToOption = ToOption with static member ($) (ToOption, x) = Some x
let inline mapTuple f (x, y) = (f $ x, f $ y)
let tuple1 = mapTuple ToString (true, 42)
let tuple2 = mapTuple ToOption (true, 42)
// val tuple1 : string * string = ("True", "42")
// val tuple2 : bool option * int option = (Some true, Some 42)
ToString will return the same type but operating with arbitrary types. ToOption will return two Generics of different types.
By using a binary operator type inference creates the static constraints for you and I use $ because in Haskell it means apply so a nice detail is that for haskellers f $ x reads already apply x to f.
At the risk of stating the obvious, a good enough solution might be to have a mapTuple that takes two functions instead of one:
let mapTuple fa fb (a, b) = (fa a, fb b)
If your original f is generic, passing it as fa and fb will give you two concrete instantiations of the function with the types you're looking for. At worst, you just need to pass the same function twice when a and b are of the same type.

Type signature of parser with existential quantification

In the beginning I had this simple type for a parser:
data Parser a = Parser ([Token] -> Either String (a, [Token]))
I use the Either for error messages on the left side and the parsed expression with the rest of the tokens on the right side.
This function "unpacks" the parser function.
parse :: Parser a -> [Token] -> Either String (a, [Token])
parse (Parser p) = p
My goal was to make the Parser more general that it does not only take tokens as input. So I used the ExistentialQuantification pragma and changed it to:
data Parser a = forall b. ([b] -> Either String (a, [b]))
What I want to know is: What type does the function "parse" have now?
I could not figure it out and it cannot be inferred. GHCi gave this error:
Couldn't match type `t' with `[b] -> Either String (t1, [b])'
`t' is a rigid type variable bound by
the inferred type of parse :: Parser t1 -> t
at ParserCombinator.hs:9:1
In the expression: p
In an equation for `parse': parse (Parser p) = p
Thanks for your help.
EDIT:
Thanks a lot for your answers.
The reason I wanted the type to look like "Parser a" because I had seen this in other parsing libraries for example in parsec.
But I saw now that this is just a shorthand for parsers that take strings as input.
It makes sense to use "data Parser b a" It was something I also tried earlier, but then I had a strange error in the monad instance for my parser, because I wrote data Parser a b instead:
import Control.Monad.Error
data Parser a b = Parser ([b] -> Either String (a, [b]))
parse (Parser p) = p
instance Monad (Parser x) where
p >>= f = Parser (\tokens -> do
(parsed, rest) <- parse p tokens
parse (f parsed) rest)
return a = Parser (\ts -> Right (a, ts))
fail b = Parser (\_ -> Left b)
It gives this error:
ParserCombinator.hs:12:18:
Couldn't match type `x' with `b'
`x' is a rigid type variable bound by
the instance declaration at ParserCombinator.hs:9:24
`b' is a rigid type variable bound by
the type signature for
>>= :: Parser x a -> (a -> Parser x b) -> Parser x b
at ParserCombinator.hs:10:5
Expected type: a
Actual type: x
In the first argument of `f', namely `parsed'
In the first argument of `parse', namely `(f parsed)'
In a stmt of a 'do' block: parse (f parsed) rest
ParserCombinator.hs:12:26:
Couldn't match type `a' with `b'
`a' is a rigid type variable bound by
the type signature for
>>= :: Parser x a -> (a -> Parser x b) -> Parser x b
at ParserCombinator.hs:10:5
`b' is a rigid type variable bound by
the type signature for
>>= :: Parser x a -> (a -> Parser x b) -> Parser x b
at ParserCombinator.hs:10:5
Expected type: [b]
Actual type: [a]
In the second argument of `parse', namely `rest'
In a stmt of a 'do' block: parse (f parsed) rest
ParserCombinator.hs:13:38:
Couldn't match type `a' with `x'
`a' is a rigid type variable bound by
the type signature for return :: a -> Parser x a
at ParserCombinator.hs:13:5
`x' is a rigid type variable bound by
the instance declaration at ParserCombinator.hs:9:24
In the expression: a
In the first argument of `Right', namely `(a, ts)'
In the expression: Right (a, ts)
Why does it work if you use Parser b a instead of Parser a b? And why do I need this x in Parser x? What does it contain?
It would be nice if you could give an example for another monad instance where this variable is used.
You mean
data Parser a = forall b. Parser ([b] -> Either String (a, [b]))
What this actually means becomes clearer if you write the existential in its more rigourous GADT notation:
data Parser a where
Parser :: forall b. ([b] -> Either String (a, [b])) -> Parser a
i.e. the constructor Parser is a universally-quantified function taking a ([b] -> ... parser, but returning always a Parser a that knows nothing about what specific b is to be used within. Therefore, this is basically useless: you can't supply a list of b token if you don't know what type that is actually supposed to be!
To make it concrete: parse would be the inverse of Parser; that swaps the quantors so it'd be an existential (duh) function
parse :: exists b . Parser a -> ([b] -> Either String (a, [b]))
Now, such a type doesn't exist in Haskell, but it's equivalent to having the arguments universal:
parse :: Parser a -> ((forall b . [b]) -> Either String (a, exists b . [b]))
At this point it's clear you can't use this in any meaningful way: the only inhabitants of forall b. [b] are [] and undefined (and, as Tikhon Jelvis remarks, [undefined], [undefined, undefined], [undefined, undefined, undefined] etc.).
I'm not sure what you actually intend to do with this type, but an existential is definitely not the right approach. Probably you should do
data Parser b a = Parser ([b] -> Either String (a, [b]))

Generic limitation in F#

Until now, I had a class like this one:
type C<'a when 'a :> A> (...)
But now I created a new type B:
type B (...) =
inherit A()
But I don't want C to support B, and this doesn't compile:
type C<'a when 'a :> A and not 'a :> B> (...)
How can I do that?
You can't and shouldn't. If B is an A, then C should handle it. If it's reasonable for C not to be able to handle B, then B shouldn't derive from A. Otherwise you're effectively breaking Liskov's Substitution Principle (or at least a variant of the same).
When you declare that B inherits from A, you're saying that it can be used as an A. If that's not the case, you shouldn't be using inheritance.

Resources