haskell create new operator, and control error - function

I have the following structure:
Terra [['0','1','0','1'],['0','1','0','1'],['1','0','G','1']]
and de function:
esTerra:: Taulell -> (Int,Int) -> Bool
esTerra t (u,d) =
case t!!!u!!!d of
Left e -> False
Right p -> True
(!!!) :: [a] -> Int -> Either Bool a
xs !!! n | n < 0 = Left False -- error Exception: Prelude.!!:...
[] !!! _ = Left False -- error Exception: Prelude.!!:...
(x:_) !!! 0 = Right x
(_:xs) !!! n = xs!!!(n-1)
the function !!! is equal the operation !! but when you have to return an error message returns False
but return error:
Couldn't match expected type ‘[a0]’
with actual type ‘Either Bool [Char]’
In the first argument of ‘(!!!)’, namely ‘t !!! u’
In the expression: t !!! u !!! d
In the expression:
case t !!! u !!! d of {
Left e -> False
Right p -> True }
Because?
Thank's

I don't know what Taulell is, let's guess Taulell = [[a]] for some a.
We have
t :: [[a]] -- Taulell
u :: Int
d :: Int
hence
t !!! u :: Either Bool [a]
Then we write
(t !!! u) !!! d
but here the leftmost argument is not a list, it's an Either Bool [a]. Hence a type error arises.
Instead, we could try, e.g.
case t !!! u of
Left b -> ...
Right l -> case l !!! d of
Left c -> ...
Rigth w -> ...

!!! needs a list as its left argument, but for a nested list it does not give a simple list as the result. It gives an Either Bool [a] as the result.
You can't use that again as the argument to !!!, but you can easily enough apply !!! to the Either-contained list:
esTerra:: Taulell -> (Int,Int) -> Bool
esTerra t (u,d) =
case t!!!u >>= (!!!d) of
Left e -> False
Right p -> True
Here, I've used the monadic bind operator >>= to combine two possibly-failing lookups into one, which will succeed only if both lookups do. This is equivalent to twice explicitly unwrapping the Either structure with a case construct, as shown by chi.

Related

Raising meaningful exceptions in Ocaml

I would like to print a meaningful message when raising a defined exception in OCaml:
type t = A | B of int
exception Wrong of t
Say I have a function
let string_of_t = function
| A -> "A"
| B n -> ("B" ^ (string_of_int n))
Then I would like to have a function
val print_exception : ( 'a -> string ) -> a' exn -> string
so that I can define
let my_raise e =
print_endline ("Error: I got the unexpected value" ^ (print_exception string_of_t e));
raise e [???]
Is there such a function print_exception ?
The problem is not very well-posed (for instance, there is no a' exn type), but I hope my intent is understandable. I've seen that one can use [##deriving sexp] but this looks like some magic outside of the language, and there is probably something easier and within the language.
There are two ways. The first one is using Printexc, the second one would be to match all the exceptions you want to print and print accordingly, something like:
exception Zero of int
exception B of string
let pp ppf = function
| Zero d -> Format.fprintf ppf "Zero of %d" d
| B s -> Format.fprintf ppf "B of %s" s
| Not_found -> Format.fprintf ppf "Not found"
| _ -> Format.fprintf ppf "Your exception is in another castle"
let f n d = if d = 0 then raise (Zero d) else n / d
let () =
let n, d = (10, 0) in
try Format.printf "%d/%d is %d#." n d (f n d)
with e ->
Format.eprintf "%a#." pp e;
Format.eprintf "%s#." (Printexc.to_string e)
Will give
❯ ./exc
Zero of 0
Exc.Zero(0)
Combining the two seems to be the best solution to be able to customise some displays and let all the others be a default one:
let pp ppf = function
| Zero d -> Format.fprintf ppf "Zero of %d" d
| e -> Format.fprintf ppf "%s" (Printexc.to_string e)
In OCaml we don't have (yet) modular implicits so unless you use [##derive ...] you need to use one of the two solutions.
As a side-note, exceptions can be caught in a pattern matching:
let () =
let n, d = (10, 0) in
match f n d with
| r -> Format.printf "%d/%d is %d#." n d r
| exception e ->
Format.eprintf "%a#." pp e;
Format.eprintf "%s#." (Printexc.to_string e)
It does semantically the same as what I wrote before but it's better for call stacks (if I'm not mistaken)
[EDIT] Looks like I forgot a third solution, see #octachron's answer
If you want to log a meaningful message before raising, it seems to me that it might be simpler to combine the logging and exception raising in one function rather than trying to reconstruct an error message from a generic unknown exception after the fact. For instance, the following function
let log_and_raise exn fmt =
Format.kfprintf
(fun ppf -> Format.pp_print_newline ppf (); raise exn)
Format.err_formatter fmt
can be used like this
exception A of int
let test n = log_and_raise (A n) "Raising the exception (A %d)" n
and will raise the exception A n after printing the error message on stderr.

Couldn't match expected type ‘Bool’ with actual type ‘a -> Bool’

I want to write a function that returns the longest prefix of a list, where applying a function to every item in that prefix produces a strictly ascending list.
For example:
longestAscendingPrefix (`mod` 5) [1..10] == [1,2,3,4]
longestAscendingPrefix odd [1,4,2,6,8,9,3,2,1] == [1]
longestAscendingPrefix :: Ord b => (a -> b) -> [a] -> [a]
longestAscendingPrefix _ [] = []
longestAscendingPrefix f (x:xs) = takeWhile (\y z -> f y <= f z) (x:xs)
This code snippet produces the error message in the title. It seems the problem lies within that lambda function.
takeWhile has type takeWhile :: (a -> Bool) -> [a] -> [a]. The first parameter is thus a function that maps an element of the list to a Bool. Your lambda expression has type Ord b => a -> a -> Bool, which does not make much sense.
You can work with explicit recursion with:
longestAscendingPrefix :: Ord b => (a -> b) -> [a] -> [a]
longestAscendingPrefix f = go
where go [] = []
go [x] = …
go (x1:x2:xs) = …
where you need to fill in the … parts the last one makes a recursive call to go.

How to Implement functions from type signatures?

I have the following two type signatures in Haskell:
foo :: (a -> (a,b)) -> a -> [b]
bar :: (a -> b) -> (a -> b -> c) -> a -> c
I want to write a concrete implementation of these two functions but I'm really struggling to understand where to start.
I understand that foo takes a function (a -> (a,b)) and returns a and a list containing b.
And bar takes a function (b -> c) which returns a function (a -> b -> c) which finally returns a and c.
Can anyone show me an example of a concrete implementation?
How do I know where to start with something like this and what goes on the left side of the definition?
You have some misunderstandings there:
I understand that foo takes a function (a -> (a,b)) and returns a and a list containing b.
No, it doesn't return a. It expects it as another argument, in addition to that function.
And bar takes a function (b -> c) which returns a function (a -> b -> c) which finally returns a and c.
Same here. Given g :: a -> b, bar returns a function bar g :: (a -> b -> c) -> a -> c. This function, in turn, given a function h :: (a -> b -> c), returns a function of type a -> c. And so it goes.
It's just like playing with pieces of a puzzle:
foo :: (a -> (a,b)) -> a -> [b]
-- g :: a -> (a,b)
-- x :: a
-- g x :: (a,b)
foo g x = [b] where
(a,b) = g x
bar :: (a -> b) -> (a -> b -> c) -> a -> c
-- g :: a -> b
-- x :: a
-- g x :: b
-- h :: a -> b -> c
-- h x :: b -> c
-- h x (g x) :: c
bar g h x = c where
c = ....
There's not much free choice for us here. Although, there are more ways to get more values of type b, for foo. Instead of ignoring that a in (a,b) = g x, we can use it in more applications of g, so there actually are many more possibilities there, like
foo2 :: (a -> (a,b)) -> a -> [b]
foo2 g x = [b1,b2] where
(a1,b1) = g x
(a2,b2) = g a1
and many more. Still, the types guide the possible implementations. foo can even make use of foo in its implementation, according to the types:
foo3 :: (a -> (a,b)) -> a -> [b]
foo3 g x = b : bs where
(a,b) = g x
bs = ...
So now, with this implementation, the previous two become its special cases: foo g x === take 1 (foo3 g x) and foo2 g x === take 2 (foo3 g x). Having the most general definition is probably best.
In addition to #will-nes's answer, it will be useful to treat (->) as a right-associative infix operator. So something like f: a -> b -> c is the same as f: a -> (b -> c). So this is saying f is a function that takes a value of type a and returns you a value of type b -> c, which is, another function, one that takes a value of type b and returns you a value of type c.
So the types in your example can be re-written as follows
foo :: (a -> (a,b)) -> (a -> [b])
bar :: (a -> b) -> ((a -> (b -> c)) -> (a -> c))
Similarly, you can think of arguments to a function in pieces as well, as being left-associative (like + and -), though there's no explicit operator in this case. foo a b c d e is the same as ((((foo a) b) c) d) e. For example, let's say we have a function f: Int -> Int -> Int (which is the same as f: Int -> (Int -> Int)). You don't have to provide both arguments at once. So you can write g = f 1, which has the type (Int -> Int). And then you can provide an argument to g, like g 2, which has the type Int. f 1 2 and let g = f 1 in g 2 are more or less the same. Here's a more concrete example of how this works:
Prelude> f = (+)
Prelude> g = f 1
Prelude> g 2
3
Prelude> :t f
f :: Num a => a -> a -> a
Prelude> :t g
g :: Num a => a -> a
Prelude> :t g 2
g 2 :: Num a => a
In #will-nes's sample implementation examples, he defines the functions with all of the arguments up front, but you don't have to think of them that way. Just think of f: a -> b -> c as taking a value of type a and returning another function. While most of the methods you encounter will use all of their arguments up-front, there might be cases in which you don't want to do that. Here's an example:
veryExpensive :: A -> B
unstagedFun :: A -> (B -> C) -> C
unstagedFun a f = f (veryExpensive a)
stagedFun :: A -> (B -> C) -> C
stagedFun a = let b = veryExpensive a in \f -> f b
(You can also rewrite the latter as let b = veryExpensive a in ($ b))
Of course, with compiler optimizations, I wouldn't be surprised if the unstaged version staged automatically, but hopefully this offers some motivation for thinking of functions as not having multiple arguments, but rather, as a single argument, but they may return other functions that may themselves return functions (but also only take a single argument).

Polymorphic types in Haskell

I came across this function
iter p f x = if (p x) then x else (iter p f (f x))
and I thought I'd give a go at defining the polymorphic types myself to understand the concept.
My thought was the following:
The function takes 3 parameters, so we have t1 -> t2 -> t3 -> T
p is being used inside the if condition so it must return a bool, therefore t1 = a -> Bool
f is also the same type as p because it is passed as an argument in the else block, therefore t2 = a -> Bool
x is being used inside the if condition so it must return a bool, therefore t1 = a -> Bool
But when i checked the type in the ghci, the type they gave me was
iter :: (t -> Bool) -> (t -> t) -> t -> t
Can someone please explain the reasoning behind this.
Thanks
The function takes 3 parameters, so we have t1 -> t2 -> t3 -> T
This is correct as a starting point.
p is being used inside the if condition so it must return a bool, therefore t1 = a -> Bool
Correct.
f is also the same type as p because it is passed as an argument in the else block, therefore t2 = a -> Bool
Incorrect. f is never used in the same way as p. In the else block f is being applied to x and the result passed as the last argument to iter. From that we know f x must be the same type as x so f :: a -> a.
x is being used inside the if condition so it must return a bool, therefore t1 = a -> Bool
Incorrect. In the if condition x is being used only as an argument to p. You established above p :: a -> Bool. Therefore x :: a.
But when i checked the type in the ghci, the type they gave me was
iter :: (t -> Bool) -> (t -> t) -> t -> t
Correct. You could also write this replacing t with a to be consistent in the notation - we used a above:
iter :: (a -> Bool) -> (a -> a) -> a -> a
Let's evaluate it again:
iter p f x = if (p x) then x else (iter p f (f x))
iter takes three parameters (well technically speaking every function takes one parameter, but let's skip the details). So it has indeed a type t1 -> t2 -> t3 -> t.
Now in the if-then-else statement, we see (p x) this means that p x has to evaluate to a boolean. So that means that:
t1 ~ t3 -> Bool
Next we see x in the then statement. This may strike as non-important, but it is: it means that the output type t is the same as that of t3, so:
t3 ~ t
Now that means we already derived that iter has the type:
iter :: (t3 -> Bool) -> t2 -> t3 -> t3
Now we see in the else statement the call:
iter p f (f x)
So that means that f is a function f :: t4 -> t5. Since it takes x as input, its input type should be t3, and since the result of (f x) is passed to an iter function (that is not per se the same "grounded" iter function). So we have to inspect the call:
iter :: (u3 -> Bool) -> u2 -> u3 -> u3 -- call
Now since we call it with iter p f (f x) we definitely know that u3 ~ t3: because p has type t3 -> Bool. So it grounds further to:
iter :: (t3 -> Bool) -> u2 -> t3 -> t3 -- call
Sine (f x) is used as third argument, we know that the type of the result of f x should be t3 as well. So f has type f :: t3 -> t3. So we conclude that iter has the type:
iter :: (t3 -> Bool) -> (t3 -> t3) -> t3 -> t3

Exceptions handling in OCaml

I have to write the function try_finalyze f g y x of type : ('a -> 'b) -> ('b -> 'c) -> 'c -> 'a -> 'c
knowing that:
1. if an exception is raised by f x the returned value has to be y
2. if f x doesn't raise any exception we have to return the result of g applied on f x
exception E
let try_finalyze f g y x = try g (f x) with E -> y;;
val try_finalyze : ('a -> 'b) -> ('b -> 'c) -> 'c -> 'a -> 'c = <fun>
1.Is it right how I treated the problem?
2.In this context what will do the following function:
fun f -> try_finalyze f (fun x-> Some x) None
I don't see the role of a function like (fun x-> Some x)
The answer to your first question is - not really. According to your specification function should catch any exception, not only your exception E. Maybe I'm misreading, but it will be better use the following definition:
let try_finalize f g y x = try g (f x) with exn -> y
As for the second part of the question, there're several ways in OCaml to signal an error. The two most common are:
Raise an exception
Return a value of an option type
The former variant is syntactically lighter, the later doesn't allow a caller to ignore the error condition. Sometimes you need to switch from one variant to an another. Suppose you have a function that raises an exception, and you would like to create a function with the same behavior, but returning an option value. Let's give it a name:
let with_option f = try_finalize f (fun x-> Some x) None
Then we can, for example, convert a List.hd to a function that returns an option type, depending on whether the list is empty or not:
let head x = with_option List.hd x
This function will have type 'a list -> 'a option, compare it with List.hd type 'a list -> 'a, the former will not allow to ignore the empty list case. When applied to an empty list, it will return a None value:
# head [];;
- : 'a option = None
If you write
let try_finalize f g y x = try g (f x) with _ -> y
Your function will return y if f doesn't raise an error but g does, which is not what you said you want.
To ensure that you catch only errors from f you should put f x alone in the try block:
let try_finalize f g y x =
let z = try Some (f x) with _ -> None in
match z with
| Some z -> g z
| None -> y
Exceptions may be considered bad style in a purely functional code, that's why you may want to transform a function that may raise an exception such as List.assoc : 'a -> ('a * 'b) list -> 'b into a function that does the same thing but returns an option.
That's what
let with_option f = try_finalize f (fun x-> Some x) None
does.
If I understand the problem statement correctly, I think I would do this :
let try_finalize f g y x =
try
let v = f x in g v
with _ -> y
As for question 2, suppose you have a function f that takes a value of type v and computes a result of type r. This :
fun f -> try_finalize f (fun x-> Some x) None
returns a function that tries to apply f. If it succeeds (i.e. no exception is thrown), it returns Some r. Otherwise, it returns None. Basically, it transforms a function that may throw an exception into a function that will not throw anything. The new function returns a r option instead of a r.
Maybe like this but the function doesn't have anymore the required type
let try_finalyze f g y x = match f x with
|E -> y
| _ -> g (f x) ;;