As a beginner in Ocaml, I have this current working code:
...
let ch_in = open_in input_file in
try
proc_lines ch_in
with End_of_file -> close_in ch_in;;
Now I would like to add error handling for non-existing input files, I wrote this:
let ch_in = try Some (open_in input_file) with _ -> None in
match ch_in with
| Some x -> try proc_lines x with End_of_file -> close_in x
| None -> () ;;
and get an error message: This pattern matches values of type 'a option
but is here used to match values of type exn for the last line. If I substitute None for _, I get an error about incomplete matching.
I read that exn is the exception type. I'm sure I don't understand what is really going on here, so please point me to the right direction. Thanks!
When embedding pattern matches inside other pattern matches you need to encase the embedded match with either ( ... ) or begin ... end (syntactic sugar for parentheses):
let ch_in = try Some (open_in input_file) with _ -> None in
match ch_in with
| Some x -> (try proc_lines x with End_of_file -> close_in x)
| None -> () ;;
Related
I am using opam switch: 5.0.0~beta1
I was playing around with some simple functions (on utop):
type _ Effect.t += Foo : (unit -> unit) -> unit Effect.t
let a = try perform (Foo (fun () -> Printf.printf "Hello from Foo\n ")) with
| Unhandled (Foo f) -> f ();;
Output: Hello from Foo
val a: unit = ()
This works well.
But when we change the definition of Foo effect,
type _ Effect.t += Foo : ('a -> unit) -> unit Effect.t
let a = try perform (Foo (fun n -> Printf.printf "Hello from Foo\n ")) with
| Unhandled (Foo f) -> f 45;;
Error: This expression has type int but an expression was expected of type
$Foo_'a
Here I understand that it needs 'a as an input, but while calling the function, shouldnt it infer the type as int and replace 'a with int and execute the function accordingly? I want to call function f from Foo effect with different argument.
Here is the another example:
type _ Effect.t += Suspend : 'a -> unit Effect.t
let a = try perform (Suspend 32) with
| Unhandled (Suspend x) -> x;;
Error: This expression has type $Suspend_'a
but an expression was expected of type $Unhandled_'a
Here, I understand that return value of (try _ with) i.e. (unit) should be the type of $Unhandled_ 'a.
But I also want to know, what is $Unhandled_ 'a type? How is normal 'a is different from $Unhandled_ 'a? How to return $Unhandled_ 'a here? Why there is this special use of $Unhandled?
What will be its scope (In some examples where I was using following code,
type _ Effect.t += Foo : ('a -> unit) -> unit Effect.t
let p = try Lwt.return (some_function x) with
| Unhandled (Foo f) -> let (pr, res) = Lwt.task () in
let wkup v = (Lwt.wakeup res v; ()) in
f wkup;
pr
I also got error as :
This expression has type $Unhandled_'a Lwt.t
but an expression was expected of type 'a Lwt.t
The type constructor $Unhandled_'a would escape its scope
)?
Why there is
The type constructor $Unhandled_'a would escape its scope
error?
The effect part is a red-herring here, the root issue stems from the notion of existentially-quantified types in GADTs.
When you have a GADT which is defined as
type t = Foo : ('a -> unit) -> t
the type of Foo means that you can construct a t for any type 'a and any function of type 'a -> unit. For instance:
let l = [Foo ignore; Foo print_int]
However, once you have constructed such value, you can no longer knows which type was used to construct the value. If you have a value
let test (Foo f) = ...
you only know that there exists some type 'a such that f has type 'a -> unit. This why the type 'a is called an existentially type (aka a type such that we only know that it exists). The important things to remember is that you don't know which 'a. Consequently you cannot apply the function because applying to the wrong 'a would be a type error.
In other words, the function boxed in Foo f can never be called on any value.
This is slightly more subtle variant than the any type
type any = Any: 'a -> any
where the constructor Any takes a value of any type and put it in a black box from which it can never be extracted.
In a way existentially-quantified type variables in a GADT lives in their own world and they cannot escape it. But they can be still be useful if this inner world is large enough. For instance, I can bundle a value with a function that prints that value and then forget the type of this value with:
type showable = Showable: {x:'a; print:'a -> unit} -> showable
Here, I can call the function print on the value x because I know that whatever is 'a it is the same 'a for both x and print:
let show (Showable {x;print}) = print x
Thus I can store few showable values in a list
let l = [ Showable(0, print_int), Showable("zero", print_string)]
and print them later
let () = List.iter show l
The minimal code:
twice :: (a -> a) -> a -> a
twice f = f . f
main = do
return twice ++ "H"
The errors generated:
stack runhaskell "c:\Users\FruitfulApproach\Desktop\Haskell\test.hs"
C:\Users\FruitfulApproach\Desktop\Haskell\test.hs:5:1: error:
* Couldn't match expected type `IO t0'
with actual type `[(a0 -> a0) -> a0 -> a0]'
* In the expression: main
When checking the type of the IO action `main'
|
5 | main = do
| ^
C:\Users\FruitfulApproach\Desktop\Haskell\test.hs:6:20: error:
* Couldn't match type `Char' with `(a -> a) -> a -> a'
Expected type: [(a -> a) -> a -> a]
Actual type: [Char]
* In the second argument of `(++)', namely `"H"'
In a stmt of a 'do' block: return twice ++ "H"
In the expression: do return twice ++ "H"
* Relevant bindings include
main :: [(a -> a) -> a -> a]
(bound at C:\Users\FruitfulApproach\Desktop\Haskell\test.hs:5:1)
|
6 | return twice ++ "H"
| ^^^
How would I logically fix this issue myself? Clearly it's something I'm doing wrong. Am I missing a preamble that every example should have?
As RobinZigmond mentions in the comments, you can’t write twice ++ "H". This means, ‘take the function twice, and append the string "H" to it’. This is clearly impossible, since ++ can only append strings and lists together. I suspect that what you meant was twice (++ "H"). This takes the function (++ "H"), which appends "H" to the end of its argument, and runs it twice.
But even if you do this, there is still a problem. Take a look at the program which is created if you do this:
twice :: (a -> a) -> a -> a
twice f = f . f
main = do
return (twice (++ "H"))
Even though this program compiles, it doesn’t do anything! You have set twice (++ "H")) as the return value of main, but the return value of main is always ignored. In order to produce output, you need to use putStrLn instead of return:
twice :: (a -> a) -> a -> a
twice f = f . f
main = do
putStrLn (twice (++ "H"))
But this program doesn’t work either! twice (++ "H") is a function, which cannot be printed. This function must be applied to a value in order to produce a result:
twice :: (a -> a) -> a -> a
twice f = f . f
main = do
putStrLn (twice (++ "H") "Starting value")
This program should finally work, giving an output of Starting valueHH when it is run.
I am trying to create a function in F* to determine the minimum element of a list, and I want to throw an exception if the list is empty. The code I have so far is below:
module MinList
exception EmptyList
val min_list: list int -> Exn int
let rec min_list l = match l with
| [] -> raise EmptyList
| single_el :: [] -> single_el
| hd :: tl -> min hd (min_list tl)
When I try to verify the file, however, I get the following error:
mcve.fst(7,10-7,15): (Error 72) Identifier not found: [raise]
1 error was reported (see above)
How can I fix this error?
This error comes up because raise is not a primitive in F* but needs to be imported from FStar.Exn (see ulib/FStar.Exn.fst), which exposes this function -- raise. Simply opening this module should be sufficient. There is one more minor issue in the code that I have also fixed below.
Here's the version of the code that goes through:
module MinList
open FStar.Exn
exception EmptyList
val min_list: list int -> Exn int (requires True) (ensures (fun _ -> True))
let rec min_list l = match l with
| [] -> raise EmptyList
| single_el :: [] -> single_el
| hd :: tl -> min hd (min_list tl)
Notice that I also have added requires and ensures clauses. This is because the Exn effect expects a these clauses to reason about the code in it. If your use case however, has exactly the above clauses (i.e., true and true), then you can use the convenient synonym for this, Ex (see ulib/FStar.Pervasives.fst). Thus, the following code is also valid and will behave exactly the same as the above code.
module MinList
open FStar.Exn
exception EmptyList
val min_list: list int -> Ex int
let rec min_list l = match l with
| [] -> raise EmptyList
| single_el :: [] -> single_el
| hd :: tl -> min hd (min_list tl)
Lets say I define a data type as follows:
data OP = Plus | Minus | Num Int deriving (Show, Eq)
Then I take a list of strings, and get a list of their respective OP values like this:
getOp :: [String] -> [OP]
getOp [] = []
getOp (x:rest)
| x == "+" = Plus:(getOp rest)
| isInfixOf "Num" x == True = Num (read (drop 4 x) :: Int):(getOp rest)
| otherwise = "-" = Minus:(getOp rest)
I then want to show the [OP] list, separated by new lines. I've done it with list of Strings easily, but not sure what to do with a list of data types.
I have the following structure as a starting point:
showOp :: [OP] -> String
showOp [] = []
showOp (o:os) = (putStr o):'\n':(showOp os)
I know the last line is wrong. I'm trying to return a [Char] in the first section, then a Char, then a recursive call. I tried some other variations for the last line (see below) with no luck.
showOp o = show o (works but not what I need. It shows the whole list, not each element on a new line
showOp o = putStrLn (show o) (epic fail)
showOp o
| o == "+" = "Plus\n":(showOp os)
| more of the same. Trying to return a [Char] instead of a Char, plus other issues.
Also, i'm not sure how the output will need to be different for the Num Int type, since I'll need to show the type name and the value.
An example i/o for this would be something like:
in:
getOp ["7","+","4","-","10"]
out:
Num 7
Plus
Num 4
Minus
Num 10
You need to look at the types of the functions and objects you are using. Hoogle is a great resource for getting function signatures.
For starters, the signature of putStr is
putStr :: String -> IO ()
but your code has putStr o, where o is not a string, and the result should not be an IO (). Do you really want showOp to print the Op, or just make a multi-line string for it?
If the former, you need the signature of showOp to reflect that:
showOp :: [Op] -> IO ()
Then you can use some do-notation to finish the function.
I'll write a solution for your given type signature. Since showOp should return a String and putStr returns an IO (), we won't be using putStr anywhere. Note that String is simply a type synonym for [Char], which is why we can treat Strings as a list.
showOp :: [Op] -> String
showOp [] = [] -- the empty list is a String
showOp (o:os) = showo ++ ('\n' : showos)
where showo = (show o) -- this is a String, i.e. [Char]
showos = showOp os -- this is also a String
Both showo and showos are Strings: both show and showOp return Strings.
We can add a single character to a list of characters using the cons operation :. We can append two lists of strings using append operator ++.
Now you might want another function
printOp :: [Op] -> IO ()
printOp xs = putStr $ showOp xs
How about:
showOp = putStrLn . unlines . map show
Note that your data constructor OP is already an instance of Show. Hence, you can actually map show into your array which contains members of type OP. After that, things become very somple.
A quick couple of notes ...
You might have wanted:
getOp :: [String] -> [OP]
getOp [] = []
getOp (x:rest)
| x == "+" = Plus:(getOp rest)
| x == "-" = Minus:(getOp rest)
| isInfixOf "Num" x == True = Num (read (drop 4 x) :: Int):(getOp rest)
| otherwise = (getOp rest)
Instead of what you have. Your program has a syntax error ...
Next, the input that you wanted to provide was probably
["Num 7","+","Num 4","-","Num 10"]
?. I guess that was a typo.
How can I return values of multiple types from a single function?
I want to do something like:
take x y | x == [] = "error : empty list"
| x == y = True
| otherwise = False
I have a background in imperative languages.
There is a type constructor called Either that lets you create a type that could be one of two types. It is often used for handling errors, just like in your example. You would use it like this:
take x y | x == [] = Left "error : empty list"
| x == y = Right True
| otherwise = Right False
The type of take would then be something like Eq a => [a] -> [a] -> Either String Bool. The convention with Either for error handling is that Left represents the error and Right represents the normal return type.
When you have an Either type, you can pattern match against it to see which value it contains:
case take x y of
Left errorMessage -> ... -- handle error here
Right result -> ... -- do what you normally would
There is several solutions to your problem, depending on your intention : do you want to make manifest in your type that your function can fail (and in this case do you want to return the cause of the failure, which may be unnecessary if there is only one mode of failure like here) or do you estimate that getting an empty list in this function shouldn't happen at all, and so want to fail immediately and by throwing an exception ?
So if you want to make explicit the possibility of failure in your type, you can use Maybe, to just indicate failure without explanation (eventually in your documentation) :
take :: (Eq a) => [a] -> [a] -> Maybe Bool
take [] _ = Nothing
take x y = x == y
Or Either to register the reason of the failure (note that Either would be the answer to "returning two types from one function" in general, though your code is more specific) :
take :: (Eq a) => [a] -> [a] -> Either String Bool
take [] _ = Left "Empty list"
take x y = Right $ x == y
Finally you can signal that this failure is completely abnormal and can't be handled locally :
take :: (Eq a) => [a] -> [a] -> Bool
take [] _ = error "Empty list"
take x y = x == y
Note that with this last way, the call site don't have to immediately handle the failure, in fact it can't, since exceptions can only be caught in the IO monad. With the first two ways, the call site have to be modified to handle the case of failure (and can), if only to itself call "error".
There is one final solution that allows the calling code to choose which mode of failure you want (using the failure package http://hackage.haskell.org/package/failure ) :
take :: (Failure String m, Eq a) => [a] -> [a] -> m Bool
take [] _ = failure "Empty list"
take x y = return $ x == y
This can mimics the Maybe and the Either solution, or you can use take as an IO Bool which will throw an exception if it fails. It can even works in a [Bool] context (returns an empty list in case of failure, which is sometimes useful).
You can use the error functions for exceptions:
take :: Eq a => [a] -> [a] -> Bool
take [] _ = error "empty list"
take x y = x == y
The three answers you've gotten so far (from Tikhon Jelvis, Jedai and Philipp) cover the three conventional ways of handling this sort of situation:
Use the error function signal an error. This is often frowned upon, however, because it makes it hard for programs that use your function to recover from the error.
Use Maybe to indicate the case where no Boolean answer can be produced.
Use Either, which is often used to do the same thing as Maybe, but can additionally include more information about the failure (Left "error : empty list").
I'd second the Maybe and Either approach, and add one tidbit (which is slightly more advanced, but you might want to get to eventually): both Maybe and Either a can be made into monads, and this can be used to write code that is neutral between the choice between those two. This blog post discusses eight different ways to tackle your problem, which includes the three mentioned above, a fourth one that uses the Monad type class to abstract the difference between Maybe and Either, and yet four others.
The blog entry is from 2007 so it looks a bit dated, but I managed to get #4 working this way:
{-# LANGUAGE FlexibleInstances #-}
take :: (Monad m, Eq a) => [a] -> [a] -> m Bool
take x y | x == [] = fail "error : empty list"
| x == y = return True
| otherwise = return False
instance Monad (Either String) where
return = Right
(Left err) >>= _ = Left err
(Right x) >>= f = f x
fail err = Left err
Now this take function works with both cases:
*Main> Main.take [1..3] [1..3] :: Maybe Bool
Just True
*Main> Main.take [1] [1..3] :: Maybe Bool
Just False
*Main> Main.take [] [1..3] :: Maybe Bool
Nothing
*Main> Main.take [1..3] [1..3] :: Either String Bool
Right True
*Main> Main.take [1] [1..3] :: Either String Bool
Right False
*Main> Main.take [] [1..3] :: Either String Bool
Left "error : empty list"
Though it's important to note that fail is controversial, so I anticipate reasonable objections to this approach. The use of fail here is not essential, though—it could be replaced with any function f :: (Monad m, ErrorClass m) => String -> m a such that f err is Nothing in Maybe and Left err in Either.