In ML language
Suppose f(x,y,z) is a function. Give an example of a definition of f that would cause the argument of f to have the type: a’ * a’ * int.
sample code
fun f1 (x,y,z) = z<5 ;
val f1 = fn : 'a * 'b * int -> bool
how I change this val to a’ * a’ * int -> bool ??
The type:
a’ * a’ * int -> bool
means that the function takes three arguments the first is of 'a type, the second also of 'a type and third of type int.
Your definition:
fun f1 (x,y,z) = z<5 ;
is in the right way since it takes a tuple, now in order to restrict the type of x,y to be equal you could write:
fun f1 (x :'a ,y :'a ,z) = z<5 ;
If you want to avoid explicit type annotations, the simplest way to make x and y the same type is to return both of them from the function but under different circumstances.
Real-world example:
- fun f (x,y,z) = if z < 0 then x else y;
val f = fn : 'a * 'a * int -> 'a
(Since the bool result type isn't mentioned in the problem description, I'm assuming it's just a consequence of your returning z < 5 and not part of the original problem.)
Related
I am working on the following exercise:
Define a function libDiv which computes the list of natural divisors of some positive integer.
First define libDivInf, such that libDivInf n i is the list of divisors of n which are lesser than or equal to i
libDivInf : int -> int -> int list
For example:
(liDivInf 20 4) = [4;2;1]
(liDivInf 7 5) = [1]
(liDivInf 4 4) = [4;2;1]
Here's is my attempt:
let liDivInf : int -> int -> int list = function
(n,i) -> if i = 0 then [] (*ERROR LINE*)
else
if (n mod i) = 0 (* if n is dividable by i *)
then
i::liDivInf n(i-1)
else
liDivInf n(i-1);;
let liDiv : int -> int list = function
n -> liDivInf n n;;
I get:
ERROR: this pattern matches values of type 'a * 'b ,but a pattern
was expected which matches values of type int
What does this error mean? How can I fix it?
You've stated that the signature of liDivInf needs to be int -> int -> int list. This is a function which takes two curried arguments and returns a list, but then bound that to a function which accepts a single tuple with two ints. And then you've recursively called it in the curried fashion. This is leading to your type error.
The function keyword can only introduce a function which takes a single argument. It is primarily useful when you need to pattern-match on that single argument. The fun keyboard can have multiple arguments specified, but does not allow for pattern-matching the same way.
It is possible to write a function without using either.
let foo = function x -> x + 1
Can just be:
let foo x = x + 1
Similarly:
let foo = function x -> function y -> x + y
Can be written:
let foo x y = x + y
You've also defined a recursive function, but not included the rec keyword. It seems you're looking for something much more like the following slightly modified version of your attempt.
let rec liDivInf n i =
if i = 0 then
[]
else if (n mod i) = 0 then
i::liDivInf n (i-1)
else
liDivInf n (i-1)
So I just started learning Haskell and I have been stuck on this for quite some time already. So I have a function that calculates a number after an offset has been minus (minimum value is 0). I managed to do this function with the types explicitly shown.
offSetter :: Int -> Int -> Int
offSetter number offset
| number - offset >= 0 = number - offset
| otherwise = 0
But when I tried to change it to use generic types as below, it keeps giving me an error. Am I doing it wrong?
offSetter :: Num a => a -> a -> a
offSetter number offset
| number - offset >= 0 = number - offset
| otherwise = 0
The error I'm getting:
* Could not deduce (Ord a) arising from a use of '>='
from the context: Num a
bound by the type signature for:
offSetter :: forall a. Num a => a -> a -> a
at src\test.hs:57:1-33
Possible fix:
add (Ord a) to the context of
the type signature for:
offSetter :: forall a. Num a => a -> a -> a
* In the expression: number - offset >= 0
In a stmt of a pattern guard for
an equation for `offSetter':
number - offset >= 0
Solved it by adding Ord a:
offSetter :: (Num a, Ord a) => a -> a -> a
offSetter number1 offSet
| number1 - offSet >= 0 = number1 - offSet
| otherwise = 0
As you discovered, you need to add the type class Ord as a constraint to the type a with the following type signature:
offSetter :: (Num a, Ord a) => a -> a -> a
This is because Ord is the typeclass with comparison operators like (>=).
So Ord is used because there are elements like Strings that is not applicable to Num?
No, since String is not a member of the Num typeclass, the original declaration already excludes it as a possible candidate for the type a. As I stated earlier, you need to use Ord in order to guarantee that the type a has the operator (>=) available.
I'm doing a school assignment in OCaml and I had a question regarding the meaning of an expression.
When defining function if I, for example, wrote:
let iter : int * (int -> int) -> (int -> int)
= fun (n,f) ->
What does (int -> int) mean? I understand the function itself receives a pair as an argument, but I don't fully understand what the parentheses mean...
The parentheses are there to disambiguate between a function of type (int -> int) - meaning it takes in a parameter of type int and returns an int - and possibly just two regular ints taken as parameters of that function. Without the first pair of parentheses for example, your iter would expect an(int, int) tuple, and in case no other parameter is present, expect an int -> int -> int as return type.
Note that the second pair of parentheses is not strictly necessary, but it can be a good indicator that you are expecting a function in return. Without that pair of parentheses, the function can be read as expect a tuple of (int, int -> int) plus another int, returning an int for example.
An example of a function with the same signature as your iter could be:
let random_func: int * (int -> int) -> (int -> int) =
fun (n, f) -> f
Find TL;DR below.
In lambda calculus (please bear with me), which is what ML-languages are rooted from, the core idea is all about abstracting an application or mapping of function to an argument. Only one argument.
λx[x + 1]
The λ in the above reads abstracting function x + 1 into an application waiting for a value for x, guard it from changing, and apply (replace the x in the function with the value and calculate).
The above in Ocaml would be equivalent to:
fun x -> x + 1
which has the type int -> int, or input type int and output type int. Now, lambda only deals with one argument at a time. How does that work with functions with multiple arguments like x*x -2*x + c (a polynomial function x2 − 2·x + c)? It evaluates the argument one at a time just like before.
λc[λx[x*x - 2*x + c]]
Thus, the output of the previous application becomes the input of the next one, and so on. The Ocaml equivalent would be
fun c x -> (x * x) - (2 * x) + c
The function has type int -> int -> int or (int -> int) -> int (chain of input -> output) If you apply the function partially to an argument x = 3, you get a reduced function like so:
fun c 3 -> (3 * 3) - (2 * 3) + c
fun c -> 9 - 6 + c
fun c -> 3 + c
at which the resulting function would have the type of int -> int. This is the basis of currying. It might look confusing at first, but it proves to be very useful and under-appreciated in imperative languages. For instance, you could do something like this:
let waiting_for_c_and_x = fun c x -> 2*x + c
let waiting_for_c = waiting_for_c_and_x 10 in
let result = waiting_for_c 2 (* result = 22 *)
TL;DR
However, using parentheses to group these chains of inputs/outputs are tricky but necessary in Ocaml because in reality the compiler cannot guess from e.g. int * int -> int if you mean an application that accepts an int * int pair as an input and return an int as an output (which we could parenthesize as (int * int) -> int) or one that accepts a pair of int and a function of type int -> int as argument (which could be written as int * (int -> int)).
Applied from Stanford Encyclopedia of Philosophy (very good read)
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"
I'm completely lost on this. It was explained that functions are right justified so that let add x y = x + y;; has a function type of int -> int -> int or int -> (int -> int).
I'm not sure how I'd define a function of type (int -> int) -> int. I was thinking I'd have the first argument be a function that passes in an int and returns an int. I've tried:
let add = fun x y -> x + y --- int -> int -> int
let add = fun f x = (f x) + 3 --- ('a -> int) -> 'a -> int
What about
let eval (f: int -> int) :int = f 0
?
fun x -> (x 1) + 1;;
- : (int -> int) -> int = <fun>
or
let foo f = (f 1) + 1;;
val foo : (int -> int) -> int = <fun>
it works like
foo (fun x -> x + 1);;
- : int = 3
Your questions is highly associated with the notion of Currying.
But before that, let me say that if you want to write a function that needs a parameter to be a function, you could declare a normal function, and just use its parameter like a function. No need to complicate it. See the ex:
let f x = x(10) + 10
Now comes the currying part. In OCaml, the parameters are semantically evaluated just one at a time, and after evaluating an argument, an anonymous function is returned. This is important because it lets you supply part of the arguments of a function, creating effectively a new function (which is called Partial Application).
In the example bellow, I use + as a function (parenthesis around an operator turn it to a normal function), to create an increment function. And apply it to the previous f function.
let incr = (+) 1
f incr
The code evaluates to f incr = incr(10) + 10 = 21
This link has more information on the topic applied to OCaml.