When an exception is raised in the code I don't get any message or anything at all printed. For example the following code:
fun test n =
if n = 1
then raise Fail ("hey")
else 2
val t = test 1
When I type
- use "test.sml";
the output is just
[opening test.sml]
val it = () : unit
I would like it to print that an exception was raised and the message ("hey")
Any ideas on how to fix this
I'm using smlnj 110.82
Because you didn't handle your exception.
You should do like:
fun test n =
if n = 1
then raise Fail ("hey")
else 2
val t = test 1 handle Fail msg => 0;
[opening practice.sml]
val test = fn : int -> int
val t = 0 : int
val it = () : unit
if you hope to see Fail msg in your screen, just take use of side effect:
fun test n =
if n = 1
then raise Fail ("hey")
else 2
val t = test 1 handle Fail msg => (print (msg ^ "\n"); 0)
[opening practice.sml]
hey
val test = fn : int -> int
val t = 0 : int
val it = () : unit
Related
I am trying to check to see whether some two files are the same and wrote the following code.
let print_test_success input1 input2 =
let ic1, ic2 = open_in input1, open_in input2 in
let rec loop i1 i2 =
match (input_line i1, input_line i2) with
| string1, string2 -> if String.trim string1 = (String.trim string2)
then loop i1 i2
else print_endline "Failed with line from file1:";
print_endline string1;
print_endline " and from line 2:";
print_endline string2
| exception End_of_file, exception End_of_file -> print_endline "Passed"
| s, exception End_of_file -> if String.trim s = ""
then loop i1 i2
else print_endline "Failed"
| exception End_of_file, s -> if String.trim s = ""
then loop i1 i2
else print_endline "Failed"
in loop ic1 ic2
;;
This sort of structure worked when I had a single input channel, but now when matching on two input channels simultaneously, it throws the exception Error: Exception patterns are not allowed in this position. Is there a way around this? I've seen other ways of reading through a file that involve using try ... with ... but if possible I'd prefer to solve this with simple matching on input_line ...
If you wrap input_line in a function that converts the exception and return value into an option, you can pattern match on that:
let input_line_opt ch =
try Some input_line ch with
| End_of_file -> None
...
match (input_line_opt i1, input_line_opt i2) with
| Some string1, Some string2 -> ...
| None, None -> ...
| Some s, None -> ...
| None, Some s -> ...
I have an maybe unusual question, but how does one match a function in F# using pattern matching?
Imagine the following:
I have multiple function signatures, which will be used multiple times, like:
binary function: int -> int -> int
unary function: int -> int
boolean function: int -> int -> bool
...
Now imagine the function evaluate, which itself takes a function f. The signature of f must be one of the listed above.
How do I match such a case?
I have tried the following things:
Test No.1 : Using delegates and Unions:
type UnaryFunction = delegate of int -> int
type BinaryFunction = delegate of (int -> int) -> int
type BooleanFunction = delegate of (int -> int) -> bool
type Functions =
| Unary of UnaryFunction
| Binary of BinaryFunction
| Boolean of BooleanFunction
// ...
let evaluate f = // signature: Functions -> string
match f with
| Unary u ->
let test_result = u.Invoke 3
sprintf "the result of the unary function is %d" test_result
| Binary b ->
let test_result = b.Invoke 315 42
sprintf "the result of the binary function is %d" test_result
| Boolean o ->
let test_result = o.Invoke 315 42
if test_result then "yeah" else "nope"
Test No.2 : Using type pattern matching and delegates:
type UnaryFunction = delegate of int -> int
type BinaryFunction = delegate of (int -> int) -> int
type BooleanFunction = delegate of (int -> int) -> bool
let evaluate f =
match f with
| ?: UnaryFunction as u ->
let test_result = u.Invoke 3
sprintf "the result of the unary function is %d" test_result
| ?: BinaryFunction as b ->
let test_result = b.Invoke 315 42
sprintf "the result of the binary function is %d" test_result
| ?: BooleanFunction as o ->
let test_result = o.Invoke 315 42
if test_result then "yeah" else "nope"
| _ -> "invalid function type"
The problem with these examples is, that delegates of ... will be matched instead of actual functions.
I would like to see somethink like this:
let evaluate f =
match f with
| ?: (int -> int) as u ->
let test_result = u 3
sprintf "the result of the unary function is %d" test_result
| ?: ((int -> int) -> int) as b ->
let test_result = b 315 42
sprintf "the result of the binary function is %d" test_result
| ?: ((int -> int) -> bool) as o ->
let test_result = o 315 42
if test_result then "yeah" else "nope"
| _ -> "invalid function type"
Does F# has a special syntax for function pattern matching?
And if not, why so? Am I missing something, or isn't it also important to be able to match functions just as anything else, as this is a functional language?
Instead of using delegates, just define the work using functions directly:
type UnaryFunction = int -> int
type BinaryFunction = int -> int -> int
type BooleanFunction = int -> int -> bool
type Functions =
| Unary of UnaryFunction
| Binary of BinaryFunction
| Boolean of BooleanFunction
// ...
let evaluate f = // signature: Functions -> string
match f with
| Unary u ->
let test_result = u 3
sprintf "the result of the unary function is %d" test_result
| Binary b ->
let test_result = b 315 42
sprintf "the result of the binary function is %d" test_result
| Boolean o ->
let test_result = o 315 42
if test_result then "yeah" else "nope"
Once you've done this, you can call them as needed (as below, showing FSI output):
> evaluate (Unary (fun x -> x + 3));;
val it : string = "the result of the unary function is 6"
> let someBinaryFunction x y = x * y;;
val someBinaryFunction : x:int -> y:int -> int
> Binary someBinaryFunction |> evaluate;;
val it : string = "the result of the binary function is 13230"
I do not know how to use Json.decode.
type alias Test =
{ a : Int
, b : Int
}
testDecoder =
object2 Test
("a" := int)
("b" := int)
main : Html
main =
let
t = "{\"a\":2, \"b\":2}"
d = decodeString testDecoder t
in
p [] [ text <| toString <| d ]
I want to get value of "a".
I do not know "Ok { a = 2, b = 2 }".
decodeString : Decoder a -> String -> Result String a
Since decodeString returns a Result String a, it could either be an error or success result. You have to do a case statement and look for Ok and Err, like so:
main : Html
main =
let
t = "{\"a\":2, \"b\":2}"
d = decodeString testDecoder t
myText =
case d of
Ok x -> toString x.a
Err msg -> msg
in
p [] [ text myText ]
The following code works properly:
local
exception exc;
fun a 0 = 0
| a n = if (n>0) then n+ b (n-1) else raise exc
and b 0 = 0
| b n = if (n>0) then n+ a (n-1) else raise exc
in
fun some n = a n
handle exc => 0;
end;
some ~4;
val some = fn : int -> int
val it = 0 : int
But if I add the following modification inside the in .. end part
in
fun some n = a n
and some2 n = b n
handle exc => 0;
end;
And have the same call some ~4;
I get the following output:
val some = fn : int -> int
val some2 = fn : int -> int
E:\Program Files\SML_NJ\\bin\.run\run.x86-win32.exe: Fatal error -- Uncaught exception exc with 0
raised at E:\GenCS\SML tutorial\some2.sml:181.49-181.52
Why is the Exception uncaught? How should I modify my code to get the wished behavior?
The handle only applies to the function some2. If you want both functions to handle exceptions,
fun some n = a n handle exc => 0
and some2 n = b n handle exc => 0
How can I return a function side-effecting lexical closure1 in Scala?
For instance, I was looking at this code sample in Go:
...
// fib returns a function that returns
// successive Fibonacci numbers.
func fib() func() int {
a, b := 0, 1
return func() int {
a, b = b, a+b
return b
}
}
...
println(f(), f(), f(), f(), f())
prints
1 2 3 5 8
And I can't figure out how to write the same in Scala.
1. Corrected after Apocalisp comment
Slightly shorter, you don't need the return.
def fib() = {
var a = 0
var b = 1
() => {
val t = a;
a = b
b = t + b
b
}
}
Gah! Mutable variables?!
val fib: Stream[Int] =
1 #:: 1 #:: (fib zip fib.tail map Function.tupled(_+_))
You can return a literal function that gets the nth fib, for example:
val fibAt: Int => Int = fib drop _ head
EDIT: Since you asked for the functional way of "getting a different value each time you call f", here's how you would do that. This uses Scalaz's State monad:
import scalaz._
import Scalaz._
def uncons[A](s: Stream[A]) = (s.tail, s.head)
val f = state(uncons[Int])
The value f is a state transition function. Given a stream, it will return its head, and "mutate" the stream on the side by taking its tail. Note that f is totally oblivious to fib. Here's a REPL session illustrating how this works:
scala> (for { _ <- f; _ <- f; _ <- f; _ <- f; x <- f } yield x)
res29: scalaz.State[scala.collection.immutable.Stream[Int],Int] = scalaz.States$$anon$1#d53513
scala> (for { _ <- f; _ <- f; _ <- f; x <- f } yield x)
res30: scalaz.State[scala.collection.immutable.Stream[Int],Int] = scalaz.States$$anon$1#1ad0ff8
scala> res29 ! fib
res31: Int = 5
scala> res30 ! fib
res32: Int = 3
Clearly, the value you get out depends on the number of times you call f. But this is all purely functional and therefore modular and composable. For example, we can pass any nonempty Stream, not just fib.
So you see, you can have effects without side-effects.
While we're sharing cool implementations of the fibonacci function that are only tangentially related to the question, here's a memoized version:
val fib: Int => BigInt = {
def fibRec(f: Int => BigInt)(n: Int): BigInt = {
if (n == 0) 1
else if (n == 1) 1
else (f(n-1) + f(n-2))
}
Memoize.Y(fibRec)
}
It uses the memoizing fixed-point combinator implemented as an answer to this question: In Scala 2.8, what type to use to store an in-memory mutable data table?
Incidentally, the implementation of the combinator suggests a slightly more explicit technique for implementing your function side-effecting lexical closure:
def fib(): () => Int = {
var a = 0
var b = 1
def f(): Int = {
val t = a;
a = b
b = t + b
b
}
f
}
Got it!! after some trial and error:
def fib() : () => Int = {
var a = 0
var b = 1
return (()=>{
val t = a;
a = b
b = t + b
b
})
}
Testing:
val f = fib()
println(f(),f(),f(),f())
1 2 3 5 8
You don't need a temp var when using a tuple:
def fib() = {
var t = (1,-1)
() => {
t = (t._1 + t._2, t._1)
t._1
}
}
But in real life you should use Apocalisp's solution.