I can evaluate dhall expressions with dhall --file ..., and I can evaluate 1 + 1 in the repl, but typing a let expression into dhall repl fails with "unexpected end of input."
➜ cat test.dhall
let x = 1
let y = 2
in x + y
➜ ~ dhall --file test.dhall
3
➜ ~ dhall repl
Welcome to the Dhall v1.41.0 REPL! Type :help for more information.
⊢ let x = 1
Error: Invalid input
(input):2:1:
|
2 | <empty line>
| ^
unexpected end of input
expecting "→", ->, :, keyword, or whitespace
⊢ 1 + 1
2
let x = 1 by itself is not a valid expression. The structure of a let ... in ... expression is such that it can start with one or more let clauses, but must end with the in clause.
If you just want to set a value in the REPL, you need to use the special :let command (which is specific to the REPL and not part of the language).
⊢ :let x = 1
x : Natural
⊢ x + 1
2
Related
I read that implications are functions. But I have a hard time trying to understand the example given in the above mentioned page:
The proof term for an implication P → Q is a function that takes
evidence for P as input and produces evidence for Q as its output.
Lemma silly_implication : (1 + 1) = 2 → 0 × 3 = 0. Proof. intros H.
reflexivity. Qed.
We can see that the proof term for the above lemma is indeed a
function:
Print silly_implication. (* ===> silly_implication = fun _ : 1 + 1 = 2
=> eq_refl
: 1 + 1 = 2 -> 0 * 3 = 0 *)
Indeed, it's a function. But its type does not look right to me. From my reading, the proof term for P -> Q should be a function with an evidence for Q as output. Then, the output of (1+1) = 2 -> 0*3 = 0 should be an evidence for 0*3 = 0, alone, right?
But the Coq print out above shows that the function image is eq_refl : 1 + 1 = 2 -> 0 * 3 = 0, instead of eq_refl: 0 * 3 = 0. I don't understand why the hypothesis 1 + 1 = 2 should appear in the output. Can anyone help explain what is going on here?
Thanks.
Your understanding is correct until:
But the Coq print out above shows that the function image is ...
I think you misunderstand the Print command. Print shows you the term associated with a definition, along with the type of the definition. It does not show the image/output of a function.
For example, the following prints the definition and type of the value x:
Definition x := 5.
Print x.
> x = 5
> : nat
Similarly, the following prints the definition and type of the function f:
Definition f := fun n => n + 2.
Print f.
> f = fun n : nat => n + 2
> : nat -> nat
If you want to see the function's codomain, you have to apply the function to a value, like so:
Definition fx := f x.
Print fx.
> fx = f x
> : nat
If you want to see the image/output of a function Print won't help you. What you need is Compute. Compute takes a term (e.g. a function application) and reduces it as far as possible:
Compute (f x).
> = 7
> : nat
I'm learning. This is something I found strange:
let test_treeways x = match x with
| _ when x < 0 -> -1
| _ when x > 0 -> 1
| _ -> 0;;
If I then call it like this:
test_threeways -10;;
I will get type mismatch error (because, as far as I understand, it interprets unary minus as if it was partial function application, so it considers the type of the expression to be int -> int. However, this:
test_threeways (-10);;
acts as expected (though this actually calculates the value, as I could understand, it doesn't pass a constant "minus ten" to the function.
So, how do you write constant negative numbers in OCaml?
You need to enclose it in order to avoid parsing amiguity. "test_threeways -10" could also mean: substract 10 from test_threeways.
And there is no function application involved. Just redefine the unary minus, to see the difference:
#let (~-) = (+) 2 ;; (* See documentation of pervarsives *)
val ( ~- ) : int -> int = <fun>
# let t = -2 ;;
val t : int = -2 (* no function application, constant negative number *)
# -t ;;
- : int = 0 (* function application *)
You can use ~- and ~-. directly (as hinted in the other answer), they are both explicitly prefix operators so parsing them is not ambiguous.
However I prefer using parentheses.
I'm trying to implement the following recursive definition for addition in F#
m + 0 := m
m + (n + 1) := (m + n) + 1
I can't seem to get the syntax correct, The closest I've come is
let rec plus x y =
match y with
| 0 -> x;
| succ(y) -> succ( plus(x y) );
Where succ n = n + 1. It throws an error on pattern matching for succ.
I'm not sure what succ means in your example, but it is not a pattern defined in the standard F# library. Using just the basic functionality, you'll need to use a pattern that matches any number and then subtract one (and add one in the body):
let rec plus x y =
match y with
| 0 -> x
| y -> 1 + (plus x (y - 1))
In F# (unlike e.g. in Prolog), you can't use your own functions inside patterns. However, you can define active patterns that specify how to decompose input into various cases. The following takes an integer and returns either Zero (for zero) or Succ y for value y + 1:
let (|Zero|Succ|) n =
if n < 0 then failwith "Unexpected!"
if n = 0 then Zero else Succ(n - 1)
Then you can write code that is closer to your original version:
let rec plus x y =
match y with
| Zero -> x
| Succ y -> 1 + (plus x y)
As Tomas said, you can't use succ like this without declaring it. What you can do is to create a discriminated union that represents a number:
type Number =
| Zero
| Succ of Number
And then use that in the plus function:
let rec plus x y =
match y with
| Zero -> x
| Succ(y1) -> Succ (plus x y1)
Or you could declare it as the + operator:
let rec (+) x y =
match y with
| Zero -> x
| Succ(y1) -> Succ (x + y1)
If you kept y where I have y1, the code would work, because the second y would hide the first one. But I think doing so makes the code confusing.
type N = Zero | Succ of N
let rec NtoInt n =
match n with
| Zero -> 0
| Succ x -> 1 + NtoInt x
let rec plus x y =
match x with
| Zero -> y
| Succ n -> Succ (plus n y)
DEMO:
> plus (Succ (Succ Zero)) Zero |> NtoInt ;;
val it : int = 2
> plus (Succ (Succ Zero)) (Succ Zero) |> NtoInt ;;
val it : int = 3
let rec plus x y =
match y with
| 0 -> x
| _ -> plus (x+1) (y-1)
Consider the following code:
x = 4
y = 5
z = (y + x)
puts z
As you'd expect, the output is 9. If you introduce a newline:
x = 4
y = 5
z = y
+ x
puts z
Then it outputs 5. This makes sense, because it's interpreted as two separate statements (z = y and +x).
However, I don't understand how it works when you have a newline within parentheses:
x = 4
y = 5
z = (y
+ x)
puts z
The output is 4. Why?
(Disclaimer: I'm not a Ruby programmer at all. This is just a wild guess.)
With parens, you get z being assigned the value of
y
+x
Which evaluates to the value of the last statement executed.
End the line with \ in order to continue the expression on the next line. This gives the proper output:
x = 4
y = 5
z = (y \
+ x)
puts z
outputs 9
I don't know why the result is unexpected without escaping the newline. I just learned never to do that.
Well you won't need the escaping character \ if your lines finishes with the operator
a = 4
b = 5
z = a +
b
puts z
# => 9
Let's say I have just called a function, f, and an error occurred somewhere in the function. I just want to be able to check out the values of different variables right before the error occurred.
Suppose my gut tells me it's a small bug, so I'm too lazy to use debug(f) and too lazy to insert browser() into the part of the function where I think things are going wrong. And I'm far too lazy to start putting in print() statements.
Here's an example:
x <- 1:5
y <- x + rnorm(length(x),0,1)
f <- function(x,y) {
y <- c(y,1)
lm(y~x)
}
Calling f(x,y) we get the following error:
Error in model.frame.default(formula = y ~ x, drop.unused.levels = TRUE) :
variable lengths differ (found for 'x')
In this example, I want grab the state of the environment just before lm() is called; that way I can call x and y and see that their lengths are different. (This example may be too simple, but I hope it gets the idea across.)
As pointed out here, there's an easy way to do this, and I think this trick has the potential to change lives for the better.
First, call this:
options(error=recover)
Now when we call f(x,y) we will have an option to choose an environment to recover. Here I select option 1, which opens up a debugger and lets me play around with variables just before lm() is called.
> f(x,y)
Error in model.frame.default(formula = y ~ x, drop.unused.levels = TRUE) :
variable lengths differ (found for 'x')
Enter a frame number, or 0 to exit
1: f(x, y)
2: lm(y ~ x)
3: eval(mf, parent.frame())
4: eval(expr, envir, enclos)
5: model.frame(formula = y ~ x, drop.unused.levels = TRUE)
6: model.frame.default(formula = y ~ x, drop.unused.levels = TRUE)
Selection: 1
Called from: eval(expr, envir, enclos)
Browse[1]> x
[1] 1 2 3 4 5
Browse[1]> y
[1] 1.6591197 0.5939368 4.3371049 4.4754027 5.9862130 1.0000000
You could also just use the debug() function:
> debug(f)
> f(x,y)
debugging in: f(x, y)
debug: {
y <- c(y, 1)
lm(y ~ x)
}
Browse[1]>
debug: y <- c(y, 1)
Browse[1]> x
[1] 1 2 3 4 5
Browse[1]> y
[1] 2.146553 2.610003 2.869081 2.758753 4.433881
options(error=recover)
Probably answers the question best. However, I wanted to mention another handy debugging tool, traceback(). Calling this right after an error has occurred is often enough to pinpoint the bug.