Purescript: Could not match type - purescript

In the REPL this works:
> mm n = (\n -> n * 2) <$> n
> mm (2:3:Nil)
(4 : 6 : Nil)
in a file this compiles and I can run it:
squareOf ls =
map (\n -> n * n) ls
however when I add a type definition to that function
squareOf :: List Int -> Int
squareOf ls =
map (\n -> n * n) ls
I get an error:
Could not match type
List Int
with type
Int
while checking that type t0 t1
is at least as general as type Int
while checking that expression (map (\n ->
(...) n
)
)
ls
has type Int
in value declaration squareOf
where t0 is an unknown type
t1 is an unknown type
I tried changing the signature to a type alias of the list, and also I tried a forall definition with no luck.
If I inspect the definition created when I don't put signatures in my function I get:
forall t2 t3. Functor t2 => Semiring t3 => t2 t3 -> t2 t3
Can anyone explain why my signature is incorrect and also why am I getting this signature for the function?
Cheers
Edit: Thanks for the comments, updating the fn definition so it returns a List Int as well, and , of course it solves the problem

Assuming you're repl function is the behaviour you're after, you've missed out the map operator (<$>) in your later definitions.
Your repl function (with variables renamed for clarity) has the type:
mm :: forall f. Functor f => f Int -> f Int
mm ns = (\n -> n * 2) <$> ns
Which is to say: mm maps "times two" to something that is mappable" (i.e. a Functor)
Aside: you could be more concise/clear in your definition here:
mm :: forall f. Functor f => f Int -> f Int
mm = map (_*2)
This is similar to your squareOf definition, only now you're squaring so your use of (*) is more general:
squareOf :: forall f. Functor f => Semiring n => f n -> f n
squareOf = map \n -> n * n
Because (*) is a member of the Semiring typeclass.
But the signature you gave it suggests you're after some kind of fold? Let me know what output you expect from your squareOf function and I'll update the answer accordingly.

Here is map:
class Functor f where
map :: forall a b. (a -> b) -> f a -> f b
Narrowing to List Int and Int -> Int, the compiler infers
map :: (Int -> Int) -> List Int -> List Int
So, in squareOf, the expression reduces to a list of integers, not an integer. That is why the compiler complains.

Related

No type class instance was found, the instance head contains unknown type variables

Well, just simplified as possible:
There is a function that takes functor and does whatever
sToInt :: ∀ a s. Functor s => s a -> Int
sToInt val = unsafeCoerce val
Usage of this function with functor S which param (v) is functor too.
-- declare date type S that is functor
data S (v :: Type -> Type) a = S (v a)
instance functorS :: Functor v => Functor (S v) where
map f (S a) = S (map f a)
sV :: ∀ v a. S v a
sV = unsafeCoerce 1
sss :: Int
sss = sToInt sV -- get the error here
No type class instance was found for
Data.Functor.Functor t2
The instance head contains unknown type variables. Consider adding a type annotation.
while applying a function sToInt
of type Functor t0 => t0 t1 -> Int
to argument sV
while checking that expression sToInt sV
has type Int
in value declaration sss
where t0 is an unknown type
t1 is an unknown type
t2 is an unknown type
So it doesn't like S Functor instance has v param Functor constraint, I wonder why getting this error and how to fix it for this case.
This doesn't have to do with v or with the specific shape of S. Try this instead:
sV :: forall f a. Functor f => f a
sV = unsafeCoerce 1
sss :: Int
sss = sToInt sV
You get a similar error.
Or here's an even more simplified version:
sV :: forall a. a
sV = unsafeCoerce 1
sss :: Int
sss = sToInt sV
Again, same error.
The problem is that sToInt must get a Functor instance as a parameter (that's what the Functor s => bit in its type signature says), and in order to pick which Functor instance to pass, the compiler needs to know the type of the value. Like, if it's Maybe a, it will pass the Functor Maybe instance, and if it's Array a, it will pass the Functor Array instance, and so on.
Usually the type can be inferred from the context. For example when you say map show [1,2,3], the compiler knows that map should come from Functor Array, because [1,2,3] :: Array Int.
But in your case there is nowhere to get that information: sV can return S v for any v, and sToInt can also take any functor type. There is nothing to tell the compiler what the type should be.
And the way to fix this is obvious: if there is no context information for the compiler to get the type from, you have to tell it what the type is yourself:
sss :: Int
sss = sToInt (sV :: S Maybe _)
This will be enough for the compiler to know that v ~ Maybe, and it will be able to construct a Functor (S Maybe) instance and pass it to sToInt.
Alternatively, if you want the consumer of sss to decide what v is, you can add an extra dummy parameter to capture the type, and require that the consumer pass in a Functor v instance:
sss :: forall v. Functor v => FProxy v -> Int
sss _ = sToInt (sV :: S v _)
ddd :: Int
ddd = sss (FProxy :: FProxy Maybe)
In Haskell you can do this with visible type applications instead of FProxy, but PureScript, sadly, doesn't support that yet.
Even more alternatively, if sToInt doesn't actually care for a Functor instance, you can remove that constraint from it, and everything will work as-is:
sToInt :: forall s a. s a -> Int
sToInt a = unsafeCoerce a
sV :: forall v a. S v a
sV = unsafeCoerce 1
sss :: Int
sss = sToInt sV
This works because PureScript allows for ambiguous (aka "unknown") types to exist as long as they're not used for selecting instances.

Similar record types in a list/array in purescript

Is there any way to do something like
first = {x:0}
second = {x:1,y:1}
both = [first, second]
such that both is inferred as {x::Int | r} or something like that?
I've tried a few things:
[{x:3}] :: Array(forall r. {x::Int|r}) -- nope
test = Nil :: List(forall r. {x::Int|r})
{x:1} : test -- nope
type X r = {x::Int | r}
test = Nil :: List(X) -- nope
test = Nil :: List(X())
{x:1} : test
{x:1, y:1} : test -- nope
Everything I can think of seems to tell me that combining records like this into a collection is not supported. Kind of like, a function can be polymorphic but a list cannot. Is that the correct interpretation? It reminds me a bit of the F# "value restriction" problem, though I thought that was just because of CLR restrictions whereas JS should not have that issue. But maybe it's unrelated.
Is there any way to declare the list/array to support this?
What you're looking for is "existential types", and PureScript just doesn't support those at the syntax level the way Haskell does. But you can roll your own :-)
One way to go is "data abstraction" - i.e. encode the data in terms of operations you'll want to perform on it. For example, let's say you'll want to get the value of x out of them at some point. In that case, make an array of these:
type RecordRep = Unit -> Int
toRecordRep :: forall r. { x :: Int | r } -> RecordRep
toRecordRep {x} _ = x
-- Construct the array using `toRecordRep`
test :: Array RecordRep
test = [ toRecordRep {x:1}, toRecordRep {x:1, y:1} ]
-- Later use the operation
allTheXs :: Array Int
allTheXs = test <#> \r -> r unit
If you have multiple such operations, you can always make a record of them:
type RecordRep =
{ getX :: Unit -> Int
, show :: Unit -> String
, toJavaScript :: Unit -> Foreign.Object
}
toRecordRep r =
{ getX: const r.x
, show: const $ show r.x
, toJavaScript: const $ unsafeCoerce r
}
(note the Unit arguments in every function - they're there for the laziness, assuming each operation could be expensive)
But if you really need the type machinery, you can do what I call "poor man's existential type". If you look closely, existential types are nothing more than "deferred" type checks - deferred to the point where you'll need to see the type. And what's a mechanism to defer something in an ML language? That's right - a function! :-)
newtype RecordRep = RecordRep (forall a. (forall r. {x::Int|r} -> a) -> a)
toRecordRep :: forall r. {x::Int|r} -> RecordRep
toRecordRep r = RecordRep \f -> f r
test :: Array RecordRep
test = [toRecordRep {x:1}, toRecordRep {x:1, y:1}]
allTheXs = test <#> \(RecordRep r) -> r _.x
The way this works is that RecordRep wraps a function, which takes another function, which is polymorphic in r - that is, if you're looking at a RecordRep, you must be prepared to give it a function that can work with any r. toRecordRep wraps the record in such a way that its precise type is not visible on the outside, but it will be used to instantiate the generic function, which you will eventually provide. In my example such function is _.x.
Note, however, that herein lies the problem: the row r is literally not known when you get to work with an element of the array, so you can't do anything with it. Like, at all. All you can do is get the x field, because its existence is hardcoded in the signatures, but besides the x - you just don't know. And that's by design: if you want to put anything into the array, you must be prepared to get anything out of it.
Now, if you do want to do something with the values after all, you'll have to explain that by constraining r, for example:
newtype RecordRep = RecordRep (forall a. (forall r. Show {x::Int|r} => {x::Int|r} -> a) -> a)
toRecordRep :: forall r. Show {x::Int|r} => {x::Int|r} -> RecordRep
toRecordRep r = RecordRep \f -> f r
test :: Array RecordRep
test = [toRecordRep {x:1}, toRecordRep {x:1, y:1}]
showAll = test <#> \(RecordRep r) -> r show
Passing the show function like this works, because we have constrained the row r in such a way that Show {x::Int|r} must exist, and therefore, applying show to {x::Int|r} must work. Repeat for your own type classes as needed.
And here's the interesting part: since type classes are implemented as dictionaries of functions, the two options described above are actually equivalent - in both cases you end up passing around a dictionary of functions, only in the first case it's explicit, but in the second case the compiler does it for you.
Incidentally, this is how Haskell language support for this works as well.
Folloing #FyodorSoikin answer based on "existential types" and what we can find in purescript-exists we can provide yet another solution.
Finally we will be able to build an Array of records which will be "isomorphic" to:
exists tail. Array { x :: Int | tail }
Let's start with type constructor which can be used to existentially quantify over a row type (type of kind #Type). We are not able to use Exists from purescript-exists here because PureScript has no kind polymorphism and original Exists is parameterized over Type.
newtype Exists f = Exists (forall a. f (a :: #Type))
We can follow and reimplement (<Ctrl-c><Ctrl-v> ;-)) definitions from Data.Exists and build a set of tools to work with such Exists values:
module Main where
import Prelude
import Unsafe.Coerce (unsafeCoerce)
import Data.Newtype (class Newtype, unwrap)
newtype Exists f = Exists (forall a. f (a :: #Type))
mkExists :: forall f a. f a -> Exists f
mkExists r = Exists (unsafeCoerce r :: forall a. f a)
runExists :: forall b f. (forall a. f a -> b) -> Exists f -> b
runExists g (Exists f) = g f
Using them we get the ability to build an Array of Records with "any" tail but we have to wrap any such a record type in a newtype before:
newtype R t = R { x :: Int | t }
derive instance newtypeRec :: Newtype (R t) _
Now we can build an Array using mkExists:
arr :: Array (Exists R)
arr = [ mkExists (R { x: 8, y : "test"}), mkExists (R { x: 9, z: 10}) ]
and process values using runExists:
x :: Array [ Int ]
x = map (runExists (unwrap >>> _.x)) arr

generalize purescript function using MonadAff

I have a question about generalizing. Starting with this function:
test0 :: String -> String
test0 s = s
we can generalize it in its argument:
test1 :: forall a. Show a => a -> String
test1 s = show s
or in its functional result:
test12 :: forall a. Show a => String -> a
test12 s = s
Now consider the following function:
test2 :: forall e. Aff e Int
test2 s = pure 0
I would like to generalize it in its functional result:
test3 :: forall e m. MonadAff e m => m e Int
test3 s = pure 0
However, I now get an error:
Could not match kind type with kind # Control.Monad.Eff.Effect while checking the kind of MonadAff e m => m e Int in value declaration test3.
I cannot understand why. Moreover, I've found an example of similar such generalizing in Hyper.Node.Server, for example in this type:
write :: forall m e. MonadAff e m => Buffer -> NodeResponse m e
The constraint MonadAff e m asserts that the monad m somehow wraps Aff e somewhere inside. But it doesn't assert that monad m itself must have a type argument e. That would be awfully restrictive, wouldn't it?
Therefore, when constructing your return type, don't apply m to e:
test3 :: forall e m. MonadAff e m => m Int
test3 = pure 0
The example you found is quite different. Here, the function is not returning a value in m, like in your test3, but rather a value NodeResponse, which is a wrapper around a function that returns m Unit.

why does the compiler give error on the following haskell code?

I am trying to study the type classes in haskell. I write the following script and the raised an error. I am unable to understand why the compiler thinks of v as an concrete type while it is just a parameter for class Boxer.
data Box1 a b = Box1 Double a [b]
class Boxer v where
foo :: (v a b) -> Double
instance Boxer (Box1 a b) where
foo (Box1 r s t) = r
it raises an error in line 7:8:
Couldn't match type `v' with `Box1'
`v' is a rigid type variable bound by
the type signature for foo :: v a b -> Double at file1.hs:4:10
Expected type: v a b
Actual type: Box1 a b
Relevant bindings include
foo :: v a b -> Double (bound at file1.hs:7:3)
In the pattern: Box1 r s t
In an equation for `foo': foo (Box1 r s t) = r
Failed, modules loaded: none.
In your instance, the compiler has to instantiate v with Box1 a b. In particular, it has to instantiate v a b with something like (Box1 a b) a b – except both a variables come from a different place; they're actually disambiguated to (Box1 a b) a1 b1. Which is the same as Box1 a b a1 b1.
foo :: Box1 a b a1 b1 -> Double
Does that make any sense?
The problem is that you're confusing a (type) function, namely Box1, with the result of applying said function to some type arguments. The kinds don't match:
GHCi> :k Boxer
Boxer :: (* -> * -> *) -> Constraint
GHCi> :k (Box1 Int String)
Box1 Int String :: *
* -> * -> * is the kind of a type function / type constructor with two arguments, so that's what Boxer needs. Whereas Box1 a b is simply a type, with no arguments. Doesn't match! OTOH,
GHCi> :k Box1
Box1 :: * -> * -> *
The particular problem was being caused by improper indentation. Though there was another thing I was doing wrong. So the following version compiled:
data Box1 a b = Box1 Double a [b]
class Boxer v where
foo :: (v a b) -> Double
instance Boxer Box1 where
foo (Box1 r s t) = r

Optional argument in a method with ocaml

I encounter a problem with a optional argument in a method class.
let me explain. I have a pathfinding class graph (in the Wally module) and one his method shorthestPath. It use a optional argument. The fact is when I call (with or not the optional argument) this method OCaml return a conflict of type :
Error: This expression has type Wally.graph
but an expression was expected of type
< getCoor : string -> int * int;
getNearestNode : int * int -> string;
shorthestPath : src:string -> string -> string list; .. >
Types for method shorthestPath are incompatible
whereas shorthestPath type is :
method shorthestPath : ?src:string -> string -> string list
I same tried to use the option format for a optional argument :
method shorthestPath ?src dst =
let source = match src with
| None -> currentNode
| Some node -> node
in
...
Only in the case where I remove the optionnal argument, OCaml stop to insult me.
Thank you in advance for your help :)
It is not very clear what your situation is but I guess the following:
let f o = o#m 1 + 2
let o = object method m ?l x = match l with Some y -> x + y | None -> x
let () = print_int (f o) (* type error. Types for method x are incompatible. *)
The use site (here the definition of f), the type of object is inferred from its context. Here, o : < x : int -> int; .. >. The method x's type is fixed here.
The object o defined later is independent from the argument of f and has the type < m : ?l:int -> int -> int; .. >. And unfortunately this type is incompatible with the other.
A workaround is to give more typing context to the use site about the optional argument:
let f o = o#m ?l:None 1 + 2 (* Explicitly telling there is l *)
let o = object method m ?l x = match l with Some y -> x + y | None -> x end
Or give the type of o:
class c = object
method m ?l x = ...
...
end
let f (o : #c) = o#m 1 + 2 (* Not (o : c) but (o : #c) to get the function more polymoprhic *)
let o = new c
let () = print_int (f o)
I think this is easier since there is usually a class declaration beforehand.
This kind of glitch between higher order use of functions with optional arguments happens also outside of objects. OCaml tries to resolve it nicely but it is not always possible. In this case:
let f g = g 1 + 2
let g ?l x = match l with Some y -> x + y | None -> x
let () = print_int (f g)
is nicely typed. Nice!
The key rule: if OCaml cannot infer about omitted optional arguments, try giving some type context about them explicitly.