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
Related
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
module Dfs = struct
let rec dfslsts g paths final =
let l = PrimePath.removeDuplicates (PrimePath.extendPaths g paths)
in
let f elem =
if (List.mem "%d" (List.flatten final) = false) then (dfslsts g ["%d"] (List.flatten l)::final)
else final
in
List.iter f (Graph.nodes g)
end
Error: This expression has type string but an expression was expected of type int list
This error occurred when I called dfslsts function, which is recursive, inside the if condition.
The function dfslsts returns a list of lists.
If I try to replace the complex expression in if statement to
if (List.mem "%d" (List.flatten final) = false) then "%d"
else "%d"
then I get
Error: This expression has type 'a -> string
but an expression was expected of type 'a -> unit
Type string is not compatible with type unit
at List.iter line.
How do I solve this problem and are we allowed to call a recursive function inside the if expression.
This is the definition of my graph type:
module Graph = struct
exception NodeNotFound of int
type graph = {
nodes : int list;
edges : (int * int) list;
}
let makeGraph () =
{
nodes = [];
edges = [];
}
let rec isNodeOf g n = List.mem n g.nodes
let nodes g = g.nodes
let edges g = g.edges
let addNode g n =
let nodes = n::g.nodes and edges = g.edges in
{
nodes;
edges;
}
let addEdge g (n1, n2) =
if ((isNodeOf g n1) = false) then
raise (NodeNotFound n1)
else if ((isNodeOf g n2) = false) then
raise (NodeNotFound n2)
else
let nodes = g.nodes
and edges = (n1, n2) :: g.edges in
{
nodes;
edges;
}
let nextNodes g n =
let rec findSuccessors edges n =
match edges with
[] -> []
| (n1, n2) :: t ->
if n1 = n then n2::findSuccessors t n
else findSuccessors t n
in
findSuccessors g.edges n
let rec lastNode path =
match path with
[] -> raise (NodeNotFound 0)
| n :: [] -> n
| _ :: t -> lastNode t
end
module Paths = struct
let extendPath g path =
let n = (Graph.lastNode path) in
let nextNodes = Graph.nextNodes g n in
let rec loop path nodes =
match nodes with
[] -> []
| h :: t -> (List.append path [h]) :: (loop path t)
in
loop path nextNodes
let rec extendPaths g paths =
match paths with
[] -> []
| h :: t -> List.append (extendPath g h) (extendPaths g t)
(* Given a list lst, return a new list with all duplicate entries removed *)
let rec removeDuplicates lst =
match lst with
[]
| _ :: [] -> lst
| h :: t ->
let trimmed = removeDuplicates t in
if List.mem h trimmed then trimmed
else h :: trimmed
end
Any expression can be a recursive function call. There are no limitations like that. Your problem is that some types don't match.
I don't see any ints in this code, so I'm wondering where the compiler sees the requirement for an int list. It would help to see the type definition for your graphs.
As a side comment, you almost certainly have a precedence problem with this code:
dfslsts g ["%d"] (List.flatten l)::final
The function call to dfslsts has higher precedence that the list cons operator ::, so this is parsed as:
(dfslsts g ["%d"] (List.flatten l)) :: final
You probably need to parenthesize like this:
dfslsts g ["%d"] ((List.flatten l) :: final)
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"
The question is similar to this question. However, this one is about exceptions, not about lazy I/O.
Here is a test:
{-# LANGUAGE ScopedTypeVariables #-}
import Prelude hiding ( catch )
import Control.Exception
fooLazy :: Int -> IO Int
fooLazy m = return $ 1 `div` m
fooStrict :: Int -> IO Int
fooStrict m = return $! 1 `div` m
test :: (Int -> IO Int) -> IO ()
test f = print =<< f 0 `catch` \(_ :: SomeException) -> return 42
testLazy :: Int -> IO Int
testLazy m = (return $ 1 `div` m) `catch` \(_ :: SomeException) -> return 42
testStrict :: Int -> IO Int
testStrict m = (return $! 1 `div` m) `catch` \(_ :: SomeException) -> return 42
So I wrote two functions fooLazy which is lazy and fooStrict which is strict, also there is two tests testLazy and testStrict, then I try to catch division by zero:
> test fooLazy
*** Exception: divide by zero
> test fooStrict
42
> testLazy 0
*** Exception: divide by zero
> testStrict 0
42
and it fails in lazy cases.
The first thing that comes to mind is to write a version of the catch function that force the evaluation on its first argument:
{-# LANGUAGE ScopedTypeVariables #-}
import Prelude hiding ( catch )
import Control.DeepSeq
import Control.Exception
import System.IO.Unsafe
fooLazy :: Int -> IO Int
fooLazy m = return $ 1 `div` m
fooStrict :: Int -> IO Int
fooStrict m = return $! 1 `div` m
instance NFData a => NFData (IO a) where
rnf = rnf . unsafePerformIO
catchStrict :: (Exception e, NFData a) => IO a -> (e -> IO a) -> IO a
catchStrict = catch . force
test :: (Int -> IO Int) -> IO ()
test f = print =<< f 0 `catchStrict` \(_ :: SomeException) -> return 42
testLazy :: Int -> IO Int
testLazy m = (return $ 1 `div` m) `catchStrict` \(_ :: SomeException) -> return 42
testStrict :: Int -> IO Int
testStrict m = (return $! 1 `div` m) `catchStrict` \(_ :: SomeException) -> return 42
it seems to work:
> test fooLazy
42
> test fooStrict
42
> testLazy 0
42
> testStrict 0
42
but I use the unsafePerformIO function here and this is scary.
I have two questions:
Can one be sure that the catch function always catches all exceptions, regardless of the nature of it first argument?
If not, is there a well-known way to deal with this kind of problems? Something like the catchStrict function is suitable?
UPDATE 1.
This is a better version of the catchStrict function by nanothief:
forceM :: (Monad m, NFData a) => m a -> m a
forceM m = m >>= (return $!) . force
catchStrict :: (Exception e, NFData a) => IO a -> (e -> IO a) -> IO a
catchStrict expr = (forceM expr `catch`)
UPDATE 2.
Here is another 'bad' example:
main :: IO ()
main = do
args <- getArgs
res <- return ((+ 1) $ read $ head args) `catch` \(_ :: SomeException) -> return 0
print res
It should be rewritten like this:
main :: IO ()
main = do
args <- getArgs
print ((+ 1) $ read $ head args) `catch` \(_ :: SomeException) -> print 0
-- or
--
-- res <- return ((+ 1) $ read $ head args) `catchStrict` \(_ :: SomeException) -> return 0
-- print res
--
-- or
--
-- res <- returnStrcit ((+ 1) $ read $ head args) `catch` \(_ :: SomeException) -> return 0
-- print res
--
-- where
returnStrict :: Monad m => a -> m a
returnStrict = (return $!)
UPDATE 3.
As nanothief noticed, there is no guarantee that the catch function always catch any exception. So one need to use it carefully.
Few tips on how to solve related problems:
Use ($!) with return, use forceM on the first argument of catch, use the catchStrict function.
I also noticed that sometimes people add some strictness to instances of their transformers.
Here is an example:
{-# LANGUAGE GeneralizedNewtypeDeriving, TypeSynonymInstances, FlexibleInstances
, MultiParamTypeClasses, UndecidableInstances, ScopedTypeVariables #-}
import System.Environment
import Prelude hiding ( IO )
import qualified Prelude as P ( IO )
import qualified Control.Exception as E
import Data.Foldable
import Data.Traversable
import Control.Applicative
import Control.Monad.Trans
import Control.Monad.Error
newtype StrictT m a = StrictT { runStrictT :: m a } deriving
( Foldable, Traversable, Functor, Applicative, Alternative, MonadPlus, MonadFix
, MonadIO
)
instance Monad m => Monad (StrictT m) where
return = StrictT . (return $!)
m >>= k = StrictT $ runStrictT m >>= runStrictT . k
fail = StrictT . fail
instance MonadTrans StrictT where
lift = StrictT
type IO = StrictT P.IO
instance E.Exception e => MonadError e IO where
throwError = StrictT . E.throwIO
catchError m h = StrictT $ runStrictT m `E.catch` (runStrictT . h)
io :: StrictT P.IO a -> P.IO a
io = runStrictT
It is essentially the identity monad transformer, but with strict return:
foo :: Int -> IO Int
foo m = return $ 1 `div` m
fooReadLn :: Int -> IO Int
fooReadLn x = liftM (`div` x) $ liftIO readLn
test :: (Int -> IO Int) -> P.IO ()
test f = io $ liftIO . print =<< f 0 `catchError` \(_ :: E.SomeException) -> return 42
main :: P.IO ()
main = io $ do
args <- liftIO getArgs
res <- return ((+ 1) $ read $ head args) `catchError` \(_ :: E.SomeException) -> return 0
liftIO $ print res
-- > test foo
-- 42
-- > test fooReadLn
-- 1
-- 42
-- ./main
-- 0
Firstly (I'm not sure if you know this already), the reason the catch doesn't work with the lazy case is the
1 `div` 0
expression isn't evaluated until it is needed, which is inside the print function. However, the catch method is applied just to the f 0 expression, not the whole print =<< f 0 expression, so the exception isn't caught. If you did:
test f = (print =<< f 0) `catch` \(_ :: SomeException) -> print 42
instead, it works correctly in both cases.
If you want to make a catch statement though that forces complete evaluation of the IO result, instead of making a new instance of NFData, you could write a forceM method, and use that in the catchStrict method:
forceM :: (Monad m, NFData a) => m a -> m a
forceM m = m >>= (return $!) . force
catchStrict :: (Exception e, NFData a) => IO a -> (e -> IO a) -> IO a
catchStrict expr = (forceM expr `catch`)
(I'm a bit surprised that forceM isn't inside the Control.DeepSeq library)
Regarding your comment:
No, the rule is the exception is only thrown when the value is computed, and that is only done when it is needed by haskell. And if haskell can delay the evaluation of something it will.
An example test function that doesn't use $!, but still causes an exception straight away (so the normal catch will catch the divide by zero exception) is:
fooEvaluated :: Int -> IO Int
fooEvaluated m = case 3 `div` m of
3 -> return 3
0 -> return 0
_ -> return 1
Haskell is forced to evaluated the "3 `div` m" expression, as it needs to match the result against 3 and 0.
As a last example, the following doesn't throw any exception, and when used with the test function returns 1:
fooNoException :: Int -> IO Int
fooNoException m = case 3 `div` m of
_ -> return 1
This is because haskell never needs to calculate "3 `div` m" expression (as _ matches everything), so it is never calculated, hence no exception is thrown.
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.