Reasonml type with multiple arguments, Error exception Failure("nth") - reason

I have got Error while compiling the following code
type shape =
| Circle int
| Square int
| Rectangle int int;
let myShape = Circle 10;
let area =
switch myShape {
| Circle r => float_of_int (r * r) *. 3.14
| Square w => float_of_int (w * w)
| Rectangle w h => float_of_int (w * h)
};
Js.log area;
Fatal error: exception Failure("nth")ninja: build stopped: subcommand
failed.
When I change the Rectangle to tuple (int, int), it works
type shape =
| Circle int
| Square int
| Rectangle (int, int);
let myShape = Circle 10;
let area =
switch myShape {
| Circle r => float_of_int (r * r) *. 3.14
| Square w => float_of_int (w * w)
| Rectangle (w, h) => float_of_int (w * h)
};
Js.log area;
Is it not possible to have multiple arguments on a data constructor?
thanks
Issue has been submitted to buckelscript https://github.com/BuckleScript/bucklescript/issues/1822

Both variants are perfectly valid Reason code. You can have constructors with multiple arguments, and you're doing it right. Apparently, the problem is in the Js.log function, that is sort of a magic function and with the n-ary constructors,the magic fails.
So, my suggestion is (i) to submit an issue in the bucklescript bug tracker and (ii) do not use the magic Js.log function, but rather derive or write your own printer function and use it.

Related

Combine prisms to focus on a value regardless of a branch

I have a sum type of possible outcomes, and in every outcome there is a certain "Result" that I want to focus on. I know how to get that "Result" from each of the outcomes (I have a bunch of prisms for that), but I don't know how to combine these prisms so that I can grab the "Result" from the whole sumtype, without worrying which case I'm on.
Simplified example:
type OneAnother = Either Int Int
exampleOneAnother :: OneAnother
exampleOneAnother = Left 10
_one :: Prism' OneAnother Int
_one = _Left
_another :: Prism' OneAnother Int
_another = _Right
_result :: Lens' OneAnother Int
_result = ???
-- How can I combine _one and _another to get result regardless whether its left or right ?
Once a prism comes to focus, it loses the context. So I don't see a way to define _result in terms of _one and _another. But you can certainly do better than resorting to unsafePartial:
import Data.Lens.Lens (Lens', lens)
import Data.Profunctor.Choice ((|||), (+++))
type OneAnother = Either Int Int
_result :: Lens' OneAnother Int
_result = lens getter setter
where
getter = identity ||| identity
setter e x = (const x +++ const x) e
Stole this from the profunctor-lens repository:
-- | Converts a lens into the form that `lens'` accepts.
lensStore :: forall s t a b . ALens s t a b -> s -> Tuple a (b -> t)
lensStore l = withLens l (lift2 Tuple)
It isn't exported somehow. With that help, the following solution should be generic enough:
import Prelude
import Control.Apply (lift2)
import Data.Lens.Common
import Data.Lens.Lens
import Data.Lens.Prism
import Data.Profunctor.Choice ((|||), (+++))
import Data.Tuple
_result :: Lens' OneAnother Int
_result = lens getter setter
where
getter = identity ||| identity
setter e x = (const x +++ const x) e
lensStore :: forall s t a b . ALens s t a b -> s -> Tuple a (b -> t)
lensStore l = withLens l (lift2 Tuple)
data ABC
= A Int
| B (Tuple Boolean Int)
| C OneAnother
lensABCInt :: Lens' ABC Int
lensABCInt = lens' case _ of
A i -> map A <$> lensStore identity i
B i -> map B <$> lensStore _2 i
C i -> map C <$> lensStore _result i
Here ABC is your target sum type. As long as its each variant has a lens, you have a lens for it as a whole.
This is the best I've got so far. Yes, unsafePartial, explicit case matching ... Really hope there is something better.
_result :: Lens' OneAnother Int
_result = lens getter setter
where
getter :: OneAnother -> Int
getter x#(Left _) = unsafePartial $ fromJust $ preview _one x
getter x#(Right _) = unsafePartial $ fromJust $ preview _another x
setter :: OneAnother -> Int -> OneAnother
setter (Left _) x = review _one x
setter (Right _) x = review _another x

In sml, why it produce Error: syntax error: deleting IN IF

I'm making a function to determine whether a tree is balanced or not.
fun balanced(tree) =
let
fun size tree =
case tree of
Lf => 0
| Br(xs,ys,zs) => 1 + size ys + size zs
fun depth tree =
case tree of
Lf => 0
| Br(xs,ys,zs) =>
let val l_count = 1 + depth ys
val r_count = 1+ depth zs
in
if l_count > r_count then l_count else r_count
end
in
if size(ys) = size(zs) andalso depth(ys) = depth(zs) then true
else if tree=Lf then true
else false
end;
But it produces these errors:
stdIn:829.18-829.20 Error: unbound variable or constructor: zs
stdIn:829.9-829.11 Error: unbound variable or constructor: ys
stdIn:829.48-829.50 Error: unbound variable or constructor: zs
stdIn:829.36-829.38 Error: unbound variable or constructor: ys
Between in and end
in
if size(ys) = size(zs) andalso depth(ys) = depth(zs) then true
else if tree=Lf then true
else false
end;
you use ys and zs that you never define before. The ys and zs you have in depth and size functions are local to these functions and not visible to balanced.
You have not provided the datatype that this function operates on. I assume it looks like this:
datatype 'a binary_tree = Lf | Br of 'a * 'a binary_tree * 'a binary_tree
You get the unbound variable errors because the code
if size(ys) = size(zs) andalso ...
does not have such variables in its scope. Those variables are only available in the scope of your helper functions. Here's some hints:
Don't name your variables xs, ys and zs when xs is in fact the value residing in the branch and ys and zs are in fact the left and right sub-trees of the branch. Better names could be x (or _ if you don't use it), left and right.
Use Int.max (x, y) instead of if x > y then x else y.
Similarly, if foo then true else false is equivalent to just foo.
So you don't need if-then-else in the body of balanced.
Perform the pattern match directly in the function argument.
It isn't necessary to know the number of elements in a sub-tree (size) to determine if it's balanced. It's only necessary to know the tree's height/depth (depth).
Move the helper functions out of this function.
They're useful in their own right.
fun size Lf = 0
| size (Br (_, left, right)) = 1 + size left + size right
fun depth Lf = 0
| depth (Br (_, left, right)) = 1 + Int.max (depth left, depth right)
Write balanced in a declarative way: An empty tree (Lf) is trivially balanced. A non-empty tree (Br ...) is balanced if the left sub-tree is balanced, the right sub-tree is balanced, and the difference of the depth of the left and the right sub-tree is not more than 1.
fun balanced Lf = true
| balanced (Br (_, left, right)) =
balanced left andalso
balanced right andalso
...the 'abs'(olute) difference of 'depth left' and 'depth right' is not more than 1...
This solution traverses the tree quite a lot: First with balanced and then with depth. You can write a solution to this exercise that only traverses the tree once by returning a tuple (is_subtree_balanced, subtree_height).
fun balanced_helper Lf = (true, 0)
| balanced_helper (Br (_, left, right)) =
let val (is_left_balanced, left_height) = balanced_helper left
in ...we can stop here if the left sub-tree isn't balanced...
let val (is_right_balanced, right_height) = balanced_helper right
in ...we can stop here if the right sub-tree isn't balanced...
...otherwise: (true, 1 + Int.max(left_height, right_height))...
end
end
fun balanced tree = #1 (balanced_helper tree)

Why my expression in StringOps.foreach is not correct

I try to calculate the product of the unicode values of a String using foreach.
scala> var s:Long = 1;"Hello".foreach(s *= _)
s: Long = 9415087488
scala> var s:Long = 1;"Hello".foreach(s = s * _)
<console>:10: error: missing parameter type for expanded function ((x$1) => s.$times(x$1))
"Hello".foreach(s = s * _)
^
I wonder why s = s * _ isn't correct here, what's the difference between s *= _ and s = s * _
The signature for the foreach function is:
def foreach(f: (A) => Unit): Unit
That is, it takes a function from type A to Unit for some appropriate type A.
So this is what I believe is happening:
In the first instance, the compiler interprets the expression s *= _ as the right-hand side of the function f (an expression returning Unit - ie nothing - meaning it is executed only for its side-effect - in this case updating the value of s). Because there is an underscore in this expression, the compiler assumes a suitable left-hand side for f.
In the second instance, the compiler can interpret the expression s = s * _ as both the left and right hand sides of f, so the s of s = should define the type A of the expression, but then it doesn't know what the underscore represents and complains.
I should note also that a more idiomatic, functional style of performing this sort of calculation would be to use a fold:
scala> val s = "Hello".foldLeft(1L)(_ * _)
s: Long = 9415087488

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.

How to divide a pair of Num values?

Here is a function that takes a pair of Integral
values and divides them:
divide_v1 :: Integral a => (a, a) -> a
divide_v1 (m, n) = (m + n) `div` 2
I invoke the function with a pair of Integral
values and it works as expected:
divide_v1 (1, 3)
Great. That's perfect if my numbers are always Integrals.
Here is a function that takes a pair of Fractional
values and divides them:
divide_v2 :: Fractional a => (a, a) -> a
divide_v2 (m, n) = (m + n) / 2
I invoke the function with a pair of Fractional
values and it works as expected:
divide_v2 (1.0, 3.0)
Great. That's perfect if my numbers are always Fractionals.
I would like a function that works regardless of whether the
numbers are Integrals or Fractionals:
divide_v3 :: Num a => (a, a) -> a
divide_v3 (m, n) = (m + n) ___ 2
What operator do I use for _?
To expand on what AndrewC said, div doesn't have the same properties that / does. For example, in maths, if a divided by b = c, then c times b == a. When working with types like Double and Float, the operations / and * satisfy this property (to the extent that the accuracy of the type allows). But when using div with Ints, the property doesn't hold true. 5 div 3 = 1, but 1*3 /= 5! So if you want to use the same "divide operation" for a variety of numeric types, you need to think about how you want it to behave. Also, you almost certainly wouldn't want to use the same operator /, because that would be misleading.
If you want your "divide operation" to return the same type as its operands, here's one way to accomplish that:
class Divideable a where
mydiv :: a -> a -> a
instance Divideable Int where
mydiv = div
instance Divideable Double where
mydiv = (/)
In GHCi, it looks like this:
λ> 5 `mydiv` 3 :: Int
1
λ> 5 `mydiv` 3 :: Double
1.6666666666666667
λ> 5.0 `mydiv` 3.0 :: Double
1.6666666666666667
On the other hand, if you want to do "true" division, you would need to convert the integral types like this:
class Divideable2 a where
mydiv2 :: a -> a -> Double
instance Divideable2 Int where
mydiv2 a b = fromIntegral a / fromIntegral b
instance Divideable2 Double where
mydiv2 = (/)
In GHCi, this gives:
λ> 5 `mydiv2` 3
1.6666666666666667
λ> 5.0 `mydiv2` 3.0
1.6666666666666667
I think you are looking for Associated Types which allows for implicit type coercion and are explained quite nicely here. Below is an example for the addition of doubles and integers.
class Add a b where
type SumTy a b
add :: a -> b -> SumTy a b
instance Add Integer Double where
type SumTy Integer Double = Double
add x y = fromIntegral x + y
instance Add Double Integer where
type SumTy Double Integer = Double
add x y = x + fromIntegral y
instance (Num a) => Add a a where
type SumTy a a = a
add x y = x + y