OCaml argument names - function

From a reading:
Labels for arguments are often the same as the variable names for
them. OCaml provides a shorthand for this case. The following are
equivalent:
let f ~name1:name2 ~name2:name2 = name1+name2
let f ~name1 ~name2 = name1 + name2
When I put in the first line I get this error
Error: Unbound value name1
Hint: Did you mean name2?
I don't understand how they're equivalent if the first line isn't a valid function.

The syntax of function arguments allows different expressions.
Given an expression expr that evaluates to a function f, the following syntax are allowed with the following rules:
expr arg (given an expression arg): evaluate arg to a value v; the result is the value of f evaluated with argument v
expr ~lbl (given a value named lbl): only when f has type lbl:a -> b for some types a and b, the result is the value of f ~lbl evaluated with argument a; OR, when f has type ?lbl:a -> b (and then, lbl must have type a for typechecking).
expr ~lbl:arg (given an expression arg): this is the same thing as let lbl = arg in exp ~lbl (except that the evaluation order of expr and arg is undefined).
expr ?lbl (given a value named lbl): only when f has type ?lbl:a -> b for some types a and b, the result is the value of f ~lbl evaluated with argument a; lbl must have type a option for typechecking. This appears mostly when forwarding optional arguments from one function to another.
expr ?lbl:arg (given an expression arg): this is the same thing as let lbl = arg in exp ?lbl (except that the evaluation order of expr and arg is undefined).

Related

Binary to Decimal Conversion in Haskell using Horners Algorithm

I am trying to implement a function here which takes a list of Bool representing binary numbers such as [True, False, False] and convert that into corresponding decimal number according to Horners method.
Function type would be [Bool] -> Int.
Algorithms which i am following is:
Horners Algorithm Visual Explanation:
So far i have implemented the logic in which it says first it will check whether the list is empty or either one element in the list [True], will give 1 and [False] will give 0.
Then in this case binToDecList (x:xs) = binToDecList' x 0 what i did to treat first element whether this is True or False.
binToDecList :: [Bool] -> Int
binToDecList [] = error "Empty List"
binToDecList [True] = 1
binToDecList [False] = 0
binToDecList (x:xs) = binToDecList' x 0
binToDecList' x d | x == True = mul (add d 1)
| otherwise = mul (add d 0)
add :: Int -> Int -> Int
add x y = x + y
mul :: Int -> Int
mul x = x * 2
I want to use the result of binToDecList' in the next iteration calling itself recursively on the next element of the list. How can i store the result and then apply it to next element of the list recursively. Any kind of help would be appreciated.
The type* of foldl tells us how it must work.
foldl :: (b -> a -> b) -> b -> [a] -> b
Clearly [a], the third argument that is a list of something, must be the list of Bool to be handed to Horner’s algorithm. That means the type variable a must be Bool.
The type variable b represents a possibly distinct type. We are trying to convert [Bool] to Int, so Int is a decent guess for b.
foldl works by chewing through a list from the left (i.e., starting with its head) and somehow combining the result so far with the next element from the list. The second argument is typically named z for “zero” or the seed value for the folding process. When foldl reaches the end of the list, it returns the accumulated value.
We can see syntactically that the first argument is some function that performs some operation on items of type b and type a to yield a b. Now, a function that ignores the a item and unconditionally results in whatever the b is would fit but wouldn’t be very interesting.
Think about how Horner’s algorithm proceeds. The numbers at the elbows of the path on your diagram represent the notional “result so far” from the previous paragraph. We know that b is Int and a is Bool, so the function passed to foldl must convert the Bool to Int and combine it with the result.
The first step in Horner’s algorithm seems to be a special case that needs to be handled differently, but foldl uses the same function all the way through. If you imagine “priming the pump” with an invisible horizontal move (i.e., multiplying by two) to begin with, we can make the types fit together like puzzle pieces. It’s fine because two times zero is still zero.
Thus, in terms of foldl, Horner’s algorithm is
horners :: [Bool] -> Int
horners = foldl f 0
where f x b =
let b' = fromEnum b
in 2*x + b'
Notice that 2*x + b' combines subsequent horizontal and vertical moves.
This also suggests how to express it in direct recursion.
horners' :: [Bool] -> Int
horners' [] = 0
horners' l = go 0 l
where -- over then down
go x [] = x
go x (b:bs) =
let b' = fromEnum b
in go (2*x + b') bs
Here the inner go loop is performing the left-fold and combining each next Bool with the result so far in i.
* A pedagogical simplification: the actual type generalizes the list type into Foldable.

Function for quantifying lists: syntax and type error (Isabelle)

I'm currently working through the 'Quantifying Lists' exercise from http://isabelle.in.tum.de/exercises/. It asks to 'Define a universal and an existential quantifier on lists using primitive recursion. Expression #{term "alls P xs"} should
be true iff #{term "P x"} holds for every element #{term x} of
#{term xs}...'
This attempt looks believable to me:
primrec alls :: "('a ⇒ bool) ⇒ 'a list ⇒ bool" where
"alls P x # [] = (if P x then True else False)"
| "alls P x # xs = (if P x then alls P xs else False)"
I'm trying to write what I would express in mathematical notation as:
alls(P,[x]) = { if Px then true otherwise false
and
alls(P, [x, ...]) = { if Px then alls(P,[...]) otherwise false.
However, Isabelle says that there is a 'type error in unification' and shows that x is being assumed to have type 'a list. I feel that I have not expressed the syntax rightly, but I am not sure how it ought to be changed.
In order to treat x # foo as a single operand it should be enclosed in parentheses: (x # foo).
However this is not the end of the story: after applying the fix above you'll get an error Nonprimitive pattern in left-hand side at "alls P [x]" ... The offending pattern is x # [] that matches a single-element list.
Lists are defined using two constructors Nil and Cons and primrec does not allow for non-primitive constructors, including single-element lists (that look like Cons x Nil). One can replace primrec with fun to avoid this error, but the issue is deeper if you want to define a total function, i.e. to handle empty lists as well.
To address this the function should have patterns for both primitive constructors Nil and Cons:
primrec alls :: "('a ⇒ bool) ⇒ 'a list ⇒ bool" where
"alls P [] = ..."
| "alls P (x # xs) = (if P x then alls P xs else False)"
The part ... is missing intentionally so that you can fill it with an appropriate value.

Fortran Class (*) in Function Result

I am encountering an error with the function detailed in this post.
The problem occurs because I am trying to return a type corresponding to the
input types. Can anyone suggest a solution? I originally had a function for each
type, and then a generic interface to group them into the same name. Now I am trying to
put everything in a single function using polymorphism.
Here is the error that gfortran is giving me.
gfortran -o build/lib/foul.o -c -ffree-form -g -J./build/lib lib/foul.f
lib/foul.f:471.45:
Function cassign (expr, a, b, wrn) Result (c)
I have tried to use an allocatable array. In the main program I then do
Character (len=65), Allocatable :: sc(:)
Integer, Allocatable :: ic(:)
Real, Allocatable :: rc(:)
Allocate (sc(1))
Allocate (ic(1))
Allocate (rc(1))
sc = cassign (ra < rb, sa, sb)
ic = cassign (ra < rb, ia, ib)
rc = cassign (ra < rb, ra, rb)
This returns the following error
gfortran -o build/utests/test_foul.o -c -ffree-form -g -J./build/lib utests/test_foul.f
utests/test_foul.f:315.7:
sc = cassign (ra < rb, sa, sb)
1
Error: Can't convert CLASS(*) to CHARACTER(1) at (1)
utests/test_foul.f:316.7:
ic = cassign (ra < rb, ia, ib)
1
Error: Can't convert CLASS(*) to INTEGER(4) at (1)
utests/test_foul.f:317.7:
rc = cassign (ra < rb, ra, rb)
1
Error: Can't convert CLASS(*) to REAL(4) at (1)
1
Error: CLASS variable 'c' at (1) must be dummy, allocatable or pointer
lib/foul.f:495.10:
c = a
1
Error: Nonallocatable variable must not be polymorphic in intrinsic
assignment at (1) - check that there is a matching specific subroutine
for '=' operator
lib/foul.f:497.10:
c = b
1
Here is the function I have coded. The variables a and b can be any of the types
Character, integer or real. And the output type should match the inputs a and b
The function type_match (a, b) returns true if the two types match, false otherwise.
Function cassign (expr, a, b, wrn) Result (c)
Logical, Intent(in) :: expr
Class (*), Intent(in) :: a, b
Logical, Intent (out), Optional :: wrn
Class (*) :: c
Logical :: warn, tma, tmb
!!$ Perform warning tests (performs type matching).
If (Present (wrn)) Then
!!$ Matching input types.
tma = type_match (a, b)
if (tma) Then
tmb = type_match (a, c)
!!$ Matching input and output types.
If (tmb) Then
If (expr) Then
c = a
Else
c = b
End If
wrn = .False.
!!$ Warning: Non-matching types.
Else
wrn = .True.
End If
Else
wrn = .True.
End If
Else
If (expr) Then
c = a
Else
c = b
End If
End If
End Function cassign
I am not sure that I recommend doing what I write below, preferring instead keeping to generics, but I will attempt to explain.
The first thing to note is that, as the error message states, for a non-dummy argument polymorphic variable (such as c) that variable must have the pointer or allocatable attribute. Here, it makes sense for the function result to be allocatable.
After adding the allocatable attribute, you seem to experience two things related to assignment of the allocatable polymorphic variable: once in the function setting the result, and once using the result of the function.
The version of gfortran you are using doesn't (apparently) support intrinsic assignment to polymorphic variables. You can use the equivalent, which arguably has the intention even clearer:
allocate (c, source=a) ! You may also need to provide bounds for c
! for some gfortran.
This is the solution to the assignment problem in the function.
With the function result, however, you are now returning a polymorphic result. That means that the variable taking the assignment must also be polymorphic, or the assignment must not be intrinsic. This is the
Error: Can't convert CLASS(*) to INTEGER(4) at (1)
error when you try intrinsic assignment.
Either make everything polymorphic, stick with generics, or use defined assignment. A simplified example follows for the latter case. [Adjust and extend as required.]
module hello_bob
interface assignment(=)
module procedure int_equal_func_class
end interface
contains
subroutine int_equal_func_class(a,b)
integer, intent(out) :: a(:)
class(*), intent(in) :: b(:)
select type (b)
type is (integer)
a = b
end select
end subroutine int_equal_func_class
function func(a)
class(*), intent(in) :: a(:)
class(*), allocatable :: func(:)
! No intrinsic assignment supported, also see note about bounds
allocate(func, source=a)
end function func
end module hello_bob
program bob
use hello_bob
integer i(4)
i=func([1,2,3,4])
print*, i
end program bob

expr is giving unexpected results

expr is giving unexpected results for 4 characters (t, n, f, y). And if you are doing some further calculation. then code is breaking. I could not understand why this is happening?
% expr (F)
F
% expr (F)*1
can't use non-numeric string as operand of "*"
And,
% expr (t)
t
% expr (n)
n
% expr (f)
f
% expr (y)
y
This is coming file for charcters : t, n, f, y. There are no variables named by these characters. It should flag variable not found or some other valid error. Am i missing some thing?
The [expr] conditions of commands such as [if] and [while] expect the expression to evaluate to a boolean, i.e., an integer or one of the following string values:
true, on, yes
false, off, no
I believe t, y, f and n are shortcuts for these.
I think you are expecting something wrong from expr.
That command is intended for evaluating expressions. It can do arithmetical operations on number, compare strings or number, execute some mathematical functions, and such.
Your lines
% expr (F)
% expr (t)
% expr (n)
% expr (f)
% expr (y)
all do the same thing: they ask to perform no operation on a literal string with higher precedence (the braces). So? There is nothing more and expr returns the string itself.
In
% expr (F)*1
however, you are trying to multiply a string to a number: an operation which is not defined. Indeed, expr gives you an error saying that one of the operands of * is a non numeric string (which number F should represent?).
With a literal string such F, or y, you can ask string comparison. For example, you can do these:
% expr F < f
1
(because in my encoding the upper case letters come before lower case ones)
% expr F == y
0
and so on.
So, expr is not giving any unexpected result, but maybe your expectations are wrong.

OCaml: Using a comparison operator passed into a function

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