I wrote a function for handling an exception if we got r2=0 and i2=0, but when I run the program I get this error:
operatii.ml:12: error: Type error in function application.
Function: = : ''a * ''a -> bool
Argument: (r2, 0.0) : real * real
Reason: Can't unify ''a to real (Requires equality type)
Found near
if r2 = 0.0 then raise ImpartitorulEsteNul else
(
(r2 * r1 - i1 * i2) / (r2 * r2 + i1 * i2),
(... * ... + ... * ...) / (... * ... + ... * ...)
)
Exception- Fail "Static Errors" raised
Here is my code:
infix %%%%;
exception ImpartitorulEsteNul;
fun (r1,i1) %%%% (r2:real,i2:real)=if r2=0.0 andalso i2=0.0 then raise ImpartitorulEsteNul
else ((r2*r1-i1*i2)/(r2*r2+i1*i2),(r2*i1+i1*i2)/(r2*r2+i1*i2));
It happens because values of type real can't be checked for equality with the normal = operator. This happens due to how floating-point numbers are represented inside a computer and, honestly, it's something I can't explain to someone else yet. However, the solution is simple. You have to use the Real.== equality operator:
infix %%%%;
infix ==;
(* Import just the == function from the Real structure. *)
(* I hope you can make sense out of this line. *)
val op == = Real.==;
exception ImpartitorulEsteNul;
fun (r1,i1) %%%% (r2:real,i2:real) =
if r2==0.0 andalso i2==0.0
then raise ImpartitorulEsteNul
else ((r2*r1-i1*i2)/(r2*r2+i1*i2),(r2*i1+i1*i2)/(r2*r2+i1*i2));
Related
I'd like to have my code take code written in another document, read it, and then use it as though it was written in the code. Say we have the following:
MODULE samplemod
CONTAINS
FUNCTION sillysum(boudary,function) RESULT(counter)
IMPLICIT NONE
REAL(KIND=8) :: boundary, counter
REAL(KIND=8), DIMENSION(:) :: function
INTEGER :: m
counter = 0.d0
DO m = 1, my_mesh%me
counter = function(m) + externalfunction
END DO
END FUNCTION sillysum
END MODULE samplemod
PROGRAM sampleprogram
USE samplemod
REAL(KIND=8), DIMENSION(:) :: function1
ALLOCATE(function1(100))
DO m=1, 100
function1(i) = i
END DO
WRITE(*,*) sillysum(100,function1)
END PROGRAM sampleprogram
Where in some external file (say 'externfunct.txt') one has written m**2. How can the Fortran code read the external function m**2, SIN(m), or even 0 and have that replace externalfunction. Here's a simpler example:
REAL(KIND=8) :: x = 2
CHARACTER(LEN=*) :: strng = "external"
WRITE(*,*) "Hello world, 2 + ", strng, " = ", 2 + external
Where in a txt file I have written I have written SIN(x).
I think there are two different approaches for this (* in fact, there seems a "third" approach also, see EDIT); one is to use a shared library, and the other is to use a parser for math expressions. The first approach is described in a Rossetastone page (Call a function in a shared library) and an SO page (Fortran dynamic libraries, load at runtime?), for example. For the second approach, you can find 3rd-party libraries by searching with "math parser" or "Fortran math parser" etc. Here, I have tried this one because it seems pretty simple (only one module and no installation). If we write a simple test program like this
program test
use interpreter, only: init, evaluate, dp => realkind
implicit none
integer, parameter :: mxvars = 10 !! consider 10 variables at most here
character(10) :: symbols( mxvars )
real(dp) :: values( mxvars ), answer
character(1000) :: funcstr !! a user-defined math expression
character(5) :: stat
!> Define variable names.
symbols( 1 ) = "x"
symbols( 2 ) = "a"
symbols( 3 ) = "b"
symbols( 4 ) = "c"
symbols( 5 ) = "foo"
!> Get a math expression.
print *, "Please input a math expression:"
read(*, "(a)") funcstr !! e.g., a * x + b
!> Init the evaluator.
call init( funcstr, symbols, stat )
if ( stat /= "ok" ) stop "stat /= ok"
!> Set values for the variables.
values( : ) = 0
values( 1 ) = 2.0_dp ! x
values( 2 ) = 10.0_dp ! a
values( 3 ) = 7.0_dp ! b
!> Evaluate.
answer = evaluate( values )
print *, "function value = ", answer
end program
and compile it as (*1)
$ gfortran -ffree-line-length-none interpreter.f90 mytest.f90
we can test various expressions as follows:
$ ./a.out
Please input a math expression:
a * x + b
function value = 27.000000000000000
$ ./a.out
Please input a math expression:
sin( a * x ) + cos( b ) + foo
function value = 1.6668475050709324
The usage of other libraries also seems very similar. Because the performance of each library may be rather different, it may be useful to try several different libraries for comparison.
(*1) The module has some lines with sind, cosd, and tand, but they are not supported by gfortran. So, to compile, I have commented them out and replaced them by stop, i.e.,
stop "sind not supported..."
! pdata(st) = sind(pdata(st))
(I guess sind(x) means sin( x * pi / 180 ), so it may be OK to define it as such.)
[EDIT]
A "third" approach may be to call the built-in eval() function in interpreted languages like Python or Julia via system(), e.g., this SO page. Although this also has a lot of weak points (and it is probably much easier to use such languages directly), calling eval() from Fortran might be useful for some specific purposes.
I'm still getting the hang of haskell, and am trying to build my first "real" coding project, i.e. one where I'm going to including testing, write up documentation, etc. I'm sufficiently new to haskell where I know I don't have a lot of the knowledge of the language necessary so that everything I want to do is immediately within reach, but that's kind of the idea, so that the act of finishing will require that I touch most of the major pieces of the language.
Anyway, so the current issue I'm having is regarding throwing and catching exceptions in the language, something that I understand can be done with quite varied approaches. I have a function here, toLower:
toLower :: String -> String
toLower plaintext =
if (catch (nonAlpha plaintext) handlerNonAlpha)
then map charToLower plaintext
else exitFailure
Which will take a string, throw an exception and exit if the string includes any non-alpha characters (so if not A-Z or a-z), or if not convert the string to lowercase. So what I have for the nonAlpha function is:
--- detect non-alpha character - throw error if existant
data NonNumericException = NonNumException
instance Exception NonNumericException
handlerNonAlpha :: NonNumericException -> IO()
handlerNonAlpha ex =
putStrLn "Caught Exception: " ++ (show ex) ++ " - A non-alpha character was included in the plaintext."
nonAlpha :: String -> Bool
nonAlpha str =
let nonalphas = [x | x <- str, (ord x) < 65 || (90 < (ord x) && (ord x) < 97) || 123 < (ord x)]
in if (length nonalphas) == 0
then True
else throw NonNumException
As I said I'm pretty new to haskell, so I'm a little vague on how this data/instance structure works, but as I understand it I'm defining an parent NonNumericException, of which NonNumException is a child (and I could have more), and in the instance line defining them to be Exceptions. The catch structure, if it detects an exception (for instance, when one is thrown at the end of nonAlpha if there is a non-alpha character), then calls the handler.
So here are the compile errors that I get:
utilities.hs:61:3:
Couldn't match expected type `[Char]' with actual type `IO ()'
In the return type of a call of `putStrLn'
In the first argument of `(++)', namely
`putStrLn "Caught Exception: "'
In the expression:
putStrLn "Caught Exception: "
++
(show ex)
++ " - A non-alpha character was included in the plaintext."
utilities.hs:61:3:
Couldn't match expected type `IO ()' with actual type `[Char]'
In the expression:
putStrLn "Caught Exception: "
++
(show ex)
++ " - A non-alpha character was included in the plaintext."
In an equation for `handlerNonAlpha':
handlerNonAlpha ex
= putStrLn "Caught Exception: "
++
(show ex)
++ " - A non-alpha character was included in the plaintext."
utilities.hs:73:7:
Couldn't match expected type `Bool' with actual type `IO ()'
In the return type of a call of `catch'
In the expression: (catch (nonAlpha plaintext) handlerNonAlpha)
In the expression:
if (catch (nonAlpha plaintext) handlerNonAlpha) then
map charToLower plaintext
else
exitFailure
utilities.hs:73:14:
Couldn't match expected type `IO ()' with actual type `Bool'
In the return type of a call of `nonAlpha'
In the first argument of `catch', namely `(nonAlpha plaintext)'
In the expression: (catch (nonAlpha plaintext) handlerNonAlpha)
utilities.hs:75:8:
Couldn't match type `IO a0' with `[Char]'
Expected type: String
Actual type: IO a0
In the expression: exitFailure
In the expression:
if (catch (nonAlpha plaintext) handlerNonAlpha) then
map charToLower plaintext
else
exitFailure
In an equation for `toLower':
toLower plaintext
= if (catch (nonAlpha plaintext) handlerNonAlpha) then
map charToLower plaintext
else
exitFailure
So I guess my two question are, a) what's going wrong with the types for the handler (the line 61 errors), and b) how do I properly set the types for the functions that may throw an exception or exit with failure, but otherwise will return a bool or a string?
EDIT: I guess I should note. I do see the similarities between this question and a number of others that have been asked. Part of what I'm looking for that I don't see is a description of what the structures here are actually doing, and what is best practice and why.
What is best practice in Haskell is to leverage the awesome power of its type system to avoid needing to throw/catch exceptions for pure functions. There are cases where throwing an exception can actually make sense, but for something like your toLower function you can just choose to have a different return type. For example:
-- We can factor out our check for a non-alpha character
isNonAlpha :: Char -> Bool
isNonAlpha c = c' < 65 || (90 < c' && c' < 97) || 123 < c'
where c' = ord c
-- Why throw an exception? Just return False
hasNonAlpha :: String -> Bool
hasNonAlpha str = any isNonAlpha str
-- Renamed to not conflict with Data.Char.toLower
myToLower :: String -> Maybe String
myToLower plaintext =
if hasNonAlpha plaintext
then Nothing
else Just $ map toLower plaintext
Not only is this cleaner code, but now we don't have to worry about error handling at all, and someone else using your code won't get a nasty surprise. Instead, the notion of failure is encoded at the type level. To use this as an "error handling" mechanism, just work in the Maybe monad:
doSomething :: String -> String -> Maybe String
doSomething s1 s2 = do
s1Lower <- myToLower s1
s2Lower <- myToLower s2
return $ s1Lower ++ s2Lower
If either myToLower s1 or myToLower s2 returns Nothing, then doSomething will return Nothing. There is no ambiguity, no chance for an unhandled exception, and no crashing at runtime. Haskell exceptions themselves, those thrown by the function throw, must be caught by catch, which has to execute in the IO monad. Without the IO monad, you can't catch exceptions. In pure functions, you can always represent the concept of failure with another data type without having to resort to throw, so there is no need to over-complicate code with it.
Alternative, you could have even written myToLower monadically as
import Control.Monad
-- Other code
myToLower :: String -> Maybe String
myToLower plaintext = do
guard $ not $ hasNonAlpha plaintext
return $ map toLower plaintext
The guard from Control.Monad acts as a sort of filter for MonadPlus instances. Since Maybe is an instance of MonadPlus (as are lists), this gives us very simple code.
Or, if you want to pass around an error message:
type MyError = String
myToLower :: String -> Either MyError String
myToLower plaintext = if hasNonAlpha plaintext
then Left $ "The string " ++ plaintext ++ " has non-alpha character(s)"
else Right $ map toLower plaintext
Then you can change the type of doSomething to match:
doSomething :: String -> String -> Either MyError String
doSomething s1 s2 = do
s1Lower <- myToLower s1
s2Lower <- myToLower s2
return $ s1Lower ++ s2Lower
If you notice, the monadic syntax lets us change the type signature of our function without even having to change the code! Play around with this implementation to get a feel for how it works.
Learning about exceptions is useful, and they are great for handling exceptional circumstances.
The best place to read about exceptions is Simon Marlow's paper, An Extensible Dynamically-Typed Heirarchy of Exceptions. His book, Parallel Concurrent Programming in Haskell is another good resource on their use.
The following are a few comments on your question.
error on line 61
handlerNonAlpha :: NonNumericException -> IO()
handlerNonAlpha ex =
putStrLn "Caught Exception: " ++ (show ex) ++ ...
Function arguments are consumed eagerly in haskell. You'll have to modify this line as follows to perform string concatenation before calling putStrLn:
putStrLn $ "Caught Exception: " ++ (show ex) ++ ...
comment on nonAlpha
Exceptions can only be caught from an IO computation, and it's best to avoid throwing them from pure functions. Besides this, the problem with nonAlpha is that it claims to return a Bool, but actually returns either True or throws an exception. Why not just return False?
nonAlpha :: String -> Bool
nonAlpha str =
let nonalphas = [x | x <- str, (ord x) < 65 || (90 < (ord x) && (ord x) < 97) || 123 < (ord x)]
in if (length nonalphas) == 0
then True
else False
Pull your exception throwing code out of nonAlpha like so. The name of this function and its lack of return value indicate that it might throw an exception:
trapInvalid :: String -> IO ()
trapInvalid str = unless (nonAlpha str) $ throw NonNumException
I have the following code:
- exception Negative of string;
> exn Negative = fn : string -> exn
- local fun fact 0 =1
| fact n = n* fact(n-1)
in
fun factorial n=
if n >= 0 then fact n
else
raise Negative "Insert a positive number!!!"
handle Negative msg => 0
end;
What is wrong with it?? I get the error:
! Toplevel input:
! handle Negative msg => 0
! ^
! Type clash: expression of type
! int
! cannot have type
! exn
How can I fix it? I want the function to return 0, by means of exceptions, if the user enters a negative number.
I am also wondering how to display a message when the user enters a negative number, since print() returns unit, but the rest of the function returns int;
The precedence of raise and handle is a bit weird in SML. What you have written groups as
raise ((Negative "...") handle Negative msg => 0)
Consequently, you need to add parentheses around the if to get the right meaning.
On the other hand, I don't understand why you raise an exception just to catch it right away. Why not simply return 0 in the else branch?
Edit: If you want to print something and then return a result, use the semicolon operator:
(print "error"; 0)
However, I would strongly advise against doing that inside the factorial function. It's better to keep I/O and error handling separate from basic computational logic.
Here is a number of ways you can fix your code:
local
fun fact 0 = 1
| fact n = n * fact (n-1)
in
(* By using the built-in exception Domain *)
fun factorial n =
if n < 0 then raise Domain else fact n
(* Or by defining factorial for negative input *)
fun factorial n =
if n < 0 then -1 * fact (-n) else fact n
(* Or by extending the type for "no result" *)
fun factorial n =
if n < 0 then NONE else SOME (fact n)
end
val m = scala.collection.mutable.Map[String, Int]()
// this doesn't work
m += ("foo", 2)
// this does work
m += (("foo", 2))
// this works too
val barpair = ("bar", 3)
m += barpair
So what's the deal with m += ("foo" , 2) not working? Scala gives the type error:
error: type mismatch;
found : java.lang.String("foo")
required: (String, Int)
m += ("foo", 2)
^
Apparently Scala thinks that I am trying to call += with two arguments, instead of one tuple argument. Why? Isn't it unambiguous, since I am not using m.+= ?
Unfortunately a b (c, d, e, ..) desugars to a.b(c, d, e, ..). Hence the error.
Isn't it unambiguous, since I am not using m.+= ?
No, it isn't, because parenthesis can always be used when there are multiple arguments. For example:
List(1, 2, 3) mkString ("<", ", ", ">")
So you might ask, what multiple parameters? Well, the Scala API doc is your friend (or mine, at least), so I present you with:
scala> val m = scala.collection.mutable.Map[String, Int]()
m: scala.collection.mutable.Map[String,Int] = Map()
scala> m += (("foo", 2), ("bar", 3))
res0: m.type = Map(bar -> 3, foo -> 2)
In other words, += takes a vararg.
The preferred way to define map entries is to use the -> method. Like
m += ("foo" -> 2)
Which constructs a tuple. a -> b gets desugared to a.->(b). Every object in scala has a -> method.
I'm an OCaml noob. I'm trying to figure out how to handle a comparison operator that's passed into a function.
My function just tries to pass in a comparison operator (=, <, >, etc.) and an int.
let myFunction comparison x =
if (x (comparison) 10) then
10
else
x;;
I was hoping that this code would evaluate to (if a "=" were passed in):
if (x = 10) then
10
else
x;;
However, this is not working. In particular, it thinks that x is a bool, as evidenced by this error message:
This expression has type 'a -> int -> bool
but an expression was expected of type int
How can I do what I'm trying to do?
On a side question, how could I have figured this out on my own so I don't have to rely on outside help from a forum? What good resources are available?
Comparison operators like < and = are secretly two-parameter (binary) functions. To pass them as a parameter, you use the (<) notation. To use that parameter inside your function, you just treat it as function name:
let myFunction comp x =
if comp x 10 then
10
else
x;;
printf "%d" (myFunction (<) 5);; (* prints 10 *)
OCaml allows you to treat infix operators as identifiers by enclosing them in parentheses. This works not only for existing operators but for new ones that you want to define. They can appear as function names or even as parameters. They have to consist of symbol characters, and are given the precedence associated with their first character. So if you really wanted to, you could use infix notation for the comparison parameter of myFunction:
Objective Caml version 3.12.0
# let myFunction (#) x =
x # 10;;
val myFunction : ('a -> int -> 'b) -> 'a -> 'b = <fun>
# myFunction (<) 5;;
- : bool = true
# myFunction (<) 11;;
- : bool = false
# myFunction (=) 10;;
- : bool = true
# myFunction (+) 14;;
- : int = 24
#
(It's not clear this makes myFunction any easier to read. I think definition of new infix operators should be done sparingly.)
To answer your side question, lots of OCaml resources are listed on this other StackOverflow page:
https://stackoverflow.com/questions/2073436/ocaml-resources
Several possibilities:
Use a new definition to redefine your comparison operator:
let myFunction comparison x =
let (#) x y = comparison x y in
if (x # 10) then
10
else
x;;
You could also pass the # directly without the extra definition.
As another solution you can use some helper functions to define what you need:
let (/*) x f = f x
let (*/) f x = f x
let myFunction comparison x =
if x /* comparison */ 10 then
10
else
x