How can I do pattern matching in the purescript repl - purescript

I have the following in the repl
> :t foo
Tuple Int Int
I made an attempt to do pattern matching against foo
> (Tuple q w) = foo
Unexpected token '=' at line 1, column 13
So my question is: "What's the proper syntax to do pattern matching in the repl?"

Well, you should be able the following way:
(q /\ w) = foo

Related

Questions about a la carte data types

I was reading the original paper about data types a la carte and decided to try to implement the idea in Scala (I know it's already implemented in many functional libraries). Unfortunately I found the original paper is hard to comprehend and I stuck somewhere in the beginning. Then I found another paper that was easier to understand and I managed to rewrite Haskell code from the paper into Scala, you can find it here. However I still struggling to understand a few moments:
A quote from the second paper
Orignal Expr data type
data Expr = Val Int | Add Expr Expr
New type signature:
data Arith e = Val Int | Add e e
For any functor f, its induced recursive datatype, Fix f, is defined as the least fixpoint of f, implemented as follows:
data Fix f = In (f (Fix f))
Now that we have tied the recursive knot of a signature,
Fix Arith is a language equivalent to the original Expr datatype
which allowed integer values and addition.
What does it mean exactly "we have tied the recursive knot of a signature" and what does it mean Fix Arith is a language equivalent to the original Expr ?
The actual type of In is In :: f (Fix f) -> Fix f
If we try to construct a value using In construct and Val 1 variable we'll get the following result:
> :t In(Val 1)
> In(Val 1) :: Fix Arith
Scala encoding of the same data types:
sealed trait Arith[A]
case class Val[A](x: Int) extends Arith[A]
case class Add[A](a: A, b: A) extends Arith[A]
trait Fix[F[_]]
case class In[F[_]](exp: F[Fix[F]]) extends Fix[F]
fold function
The fold function has the following signature and implementation
Haskell:
fold :: Functor f => (f a -> a) -> Fix f -> a
fold f (In t) = f (fmap (fold f) t)
Scala variant I came up with
def fold[F[_] : Functor, A](f: F[A] => A): Fix[F] => A = {
case In(t) =>
val g: F[Fix[F]] => F[A] = implicitly[Functor[F]].lift(fold(f))
f(g(t))
}
The thing that I'm curious about is that in my Scala version function g has the following type F[Fix[F]] => F[A] but the type of variable t after pattern matching is LaCarte$Add with value Add(In(Val(1)),In(Val(2))), how it happens that it's valid to apply function g to LaCarte$Add ? Also, I'd very appreciate if you can help me to understand fold function ?
Quote from the paper:
The first argument of fold is an f-algebra, which provides
the behavior of each constructor associated with a given signature f.
What does it mean exactly “we have tied the ‘recursive knot’ of a signature”?
The original Expr datatype is recursive, referring to itself in its own definition:
data Expr = Val Int | Add Expr Expr
The Arith type “factors out” the recursion by replacing recursive calls with a parameter:
data Arith e = Val Int | Add e e
The original Expr type can have any depth of nesting, which we want to support with Arith as well, but the maximum depth depends on what type we choose for e:
Arith Void can’t be nested: it can only be a literal value (Val n) because we can’t construct an Add, because we can’t obtain a value of type Void (it has no constructors)
Arith (Arith Void) can have one level of nesting: the outer constructor can be an Add, but the inner constructors can only be Lit.
Arith (Arith (Arith Void)) can have two levels
And so on
What Fix Arith gives us is a way to talk about the fixed point Arith (Arith (Arith …)) with no limit on the depth.
This is just like how we can replace a recursive function with a non-recursive function and recover the recursion with the fixed-point combinator:
factorial' :: (Integer -> Integer) -> Integer -> Integer
factorial' recur n = if n <= 1 then 1 else n * recur (n - 1)
factorial :: Integer -> Integer
factorial = fix factorial'
factorial 5 == 120
What does it mean Fix Arith is a language equivalent to the original Expr?
The language (grammar) that Fix Arith represents is equivalent to the language that Expr represents; that is, they’re isomorphic: you can write a pair of total functions Fix Arith -> Expr and Expr -> Fix Arith.
How it happens that it’s valid to apply function g to LaCarte$Add?
I’m not very familiar with Scala, but it looks like Add is a subtype of Arith, so the parameter of g of type F[Fix[F]] can be filled with a value of type Arith[Fix[Arith]] which you get by matching on the In constructor to “unfold” one level of recursion.

Purescript: Could not match type

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.

How to convert partial functions to safe(Maybe) functions?

I want it to use library-defined partialfunc more convenient, or write callback with partial pattern-matching.
like this,
partialMaybe :: forall a b. (Partial => a -> b) -> a -> Maybe b
I couldn't find similar in some major libraries.
How to define it? or already defined in libs?
data ABC a = A a | B a | C a
f1 = someHigherOrderFunc $ partialMaybe \(A a) -> someFunc a -- if not 'A', return Nothing.
-- same as
f2 = someHigherOrderFunc $ case _ of A a -> Just $ someFunc a
_ -> Nothing -- requires line break, seems syntax redundant...
using: purescript 0.11.6
Edit:
I did it...
partialMaybe :: forall a b. (Partial => a -> b) -> a -> Maybe b
partialMaybe f a = runPure $ catchException (const $ pure Nothing) (Just <<< unsafePartial f <$> pure a)
this is...umm...very ugly. it's not.
'Failed pattern match' exception is thrown by the purescript.
so I think it should be able to handle by purescript.
Can't do it?
If you want an exception if a case is missed, use Partial. If you want otherwise, use Maybe or Either or another appropriate sum type.
You can catch the exception thrown from a failed pattern match. There is no way for a failed pattern match to not throw an exception.

Generating code from locales without interpretation

I would love to generate code from locale definitions directly, without interpretation. Example:
(* A locale, from the code point of view, similar to a class *)
locale MyTest =
fixes L :: "string list"
assumes distinctL: "distinct L"
begin
definition isInL :: "string => bool" where
"isInL s = (s ∈ set L)"
end
The assumptions to instantiate MyTest are executable and I can generate code for them
definition "can_instance_MyTest L = distinct L"
lemma "can_instance_MyTest L = MyTest L"
by(simp add: MyTest_def can_instance_MyTest_def)
export_code can_instance_MyTest in Scala file -
I can define a function to execute the isInL definition for arbitrary MyTest.
definition code_isInL :: "string list ⇒ string ⇒ bool option" where
"code_isInL L s = (if can_instance_MyTest L then Some (MyTest.isInL L s) else None)"
lemma "code_isInL L s = Some b ⟷ MyTest L ∧ MyTest.isInL L s = b"
by(simp add: code_isInL_def MyTest_def can_instance_MyTest_def)
However, code export fails:
export_code code_isInL in Scala file -
No code equations for MyTest.isInL
Why do I want to do such a thing?
I'm working with a locale in the context of a valid_graph similar to e.g. here but finite. Testing that a graph is valid is easy. Now I want to export the code of my graph algorithms into Scala. Of course, the code should run on arbitrary valid graphs.
I'm thinking of the Scala analogy similar to something like this:
class MyTest(L: List[String]) {
require(L.distinct)
def isInL(s: String): Bool = L contains s
}
One way to solve this is datatype refinement using invariants (see isabelle doc codegen section 3.3). Thereby the validity assumption (distinct L, in your case) can be moved into a new type. Consider the following example:
typedef 'a dlist = "{xs::'a list. distinct xs}"
morphisms undlist dlist
proof
show "[] ∈ ?dlist" by auto
qed
This defines a new type whose elements are all lists with distinct elements. We have to explicitly set up this new type for the code generator.
lemma [code abstype]: "dlist (undlist d) = d"
by (fact undlist_inverse)
Then, in the locale we have the assumption "for free" (since every element of the new type guarantees it; however, at some point we have to lift a basic set of operations from lists with distinct element to 'a dlists).
locale MyTest =
fixes L :: "string dlist"
begin
definition isInL :: "string => bool" where
"isInL s = (s ∈ set (undlist L))"
end
At this point, we are able to give (unconditional) equations to the code generator.
lemma [code]: "MyTest.isInL L s ⟷ s ∈ set (undlist L)"
by (fact MyTest.isInL_def)
export_code MyTest.isInL in Haskell file -
I found a method, thanks to chris' tips.
Define a function to test the prerequisites/assumptions to instantiate a MyTest
definition "can_instance_MyTest L = distinct L"
The command term MyTest reveals that MyTest is of type string list => bool,
this means that MyTest is a predicate that takes a parameter and tests if this parameter fulfills MyTest's assumptions.
We introduce a code equation ([code]) that replaces MyTest with the executable instance tester.
The code generator can now produce code for occurrences of e.g., MyTest [a,b,c]
lemma [code]: "MyTest = can_instance_MyTest"
by(simp add:fun_eq_iff MyTest_def can_instance_MyTest_def)
export_code MyTest in Scala file -
We yield (I replaced List[Char] with String for readability):
def can_instance_MyTest[A : HOL.equal](l: List[A]): Boolean =
Lista.distinct[A](l)
def myTest: (List[String]) => Boolean =
(a: List[String]) => can_instance_MyTest[String](a)
More readable pseudo-code:
def myTest(l: List[String]): Boolean = l.isDistinct
Now we need executable code for isInL. We utilize the predefined constant undefined. This code throws an exception if L is not distinct.
definition code_isInL :: "string list ⇒ string ⇒ bool" where
"code_isInL L s = (if can_instance_MyTest L then s ∈ set L else undefined)"
export_code code_isInL in Scala file -
We yield:
def code_isInL(l: List[String], s:String): Boolean =
(if (can_instance_MyTest[String](l)) Lista.member[String](l, s)
else sys.error("undefined"))*)
We just need to show that the code_isInL is correct:
lemma "b ≠ undefined ⟹ code_isInL L s = b ⟷ MyTest L ∧ MyTest.isInL L s = b"
by(simp add: code_isInL_def MyTest_def can_instance_MyTest_def MyTest.isInL_def)
(* Unfortunately, the other direction does not hold. The price of undefined. *)
lemma "¬ MyTest L ⟹ code_isInL L s = undefined"
by(simp add: code_isInL_def can_instance_MyTest_def MyTest_def)

Scala underscore use to simplify syntax of function literals

I have the following code:
var x = Array(1,3,4,4,1,1,3)
var m = Int.MaxValue
x.foreach((x)=>(m = m min x))
I tried to simplify last sentence to:
x.foreach((m = _ min m))
But the interpreter says:
scala> x.foreach((m = _ min m))
<console>:8: error: missing parameter type for expanded function ((x$1) => x$1.min(m))
x.foreach((m = _ min m))
^
I tried to be more explicit about the type:
scala> x.foreach((m = (_:Int) min m))
<console>:8: error: type mismatch;
found : (Int) => Int
required: Int
x.foreach((m = (_:Int) min m))
^
The compiler and I don't understand each other :(
Best regards,
Stan
First, note that
val m = x.min
does what you want, as does
val m = (Int.MaxValue /: x)(_ min _)
I will leave it to you to read more about these things (the min method on collections, and folds; note that these are not quite as fast as what you wrote).
The problem is that the compiler is getting lost with what you mean and with what valid types might be when you write the underscore, and when you add the type information it thinks that you're trying to write a function right there and assign it to m. But of course m is an Int, not a function, so it complains.
Just write it explicitly. It's only a few extra characters:
x.foreach(i => m = m min i)