Haskell Complex Function Types - function

A Haskell function I am struggling with has the following type
func1 :: (Integer -> Integer -> Integer) -> Integer -> Integer -> Integer
I am unsure of how to handle the Parenthesis piece in the actual implementation. I know that a function should be passed into the input in this scenario.
(Integer -> Integer -> Integer)

When a function is passed to you as a parameter, the only useful thing you can do with it in the end is to call it. That's what functions are for. That's what they do.
For example, in this case it may look something like this:
func1 :: (Integer -> Integer -> Integer) -> Integer -> Integer -> Integer
func1 f a b = f (a*2) (b+5)
Here, the first parameter is named f and it's a function that takes two parameters, both Integer, and returns another Integer - that much is conveyed by its type (Integer -> Integer -> Integer).
The second and third parameters are named a and b respectively, and they're both Integer.
The body of function func1 consists of calling its function-parameter f, passing it (a*2) and (b+5) as parameters.

Related

How to check if a function call having too many or too few arguments in a Haskell project

I am working on the Haskell project,
For the error checking, I need to take care of any function call having too many or too few arguments, but I currently have no idea for it.Hoping to get same hints to start.
Unless one uses some form of advanced ad hoc polymorphism like the printf :: PrintfType r => String -> r does, the compiler will notice.
Indeed, if you have a function like:
add :: Int -> Int -> Int
add = (+)
if you call it with three parameters, like add 2 4 5, then this will raise an error. This will happen, since add 2 4 5, or more canonical ((add 2) 4) 5, will try to eventually make a call to an item that is an Int. Indeed add 2 has type add 2 :: Int -> Int, and thus (add 2) 4 has type (add 2) 4 :: Int, so since that is not function, the compiler will raise an error:
Prelude> add 2 4 5
<interactive>:5:1: error:
• Couldn't match expected type ‘Integer -> t’
with actual type ‘Int’
• The function ‘add’ is applied to three arguments,
but its type ‘Int -> Int -> Int’ has only two
In the expression: add 2 4 5
In an equation for ‘it’: it = add 2 4 5
• Relevant bindings include it :: t (bound at <interactive>:5:1)
It thus says it expected a type (Integer -> t, although the Integer here is due to type defaulting), but got an Int instead. So that is not possible.
Calling a function with "too few" parameters is not really possible, since if you call it with too few, you simply generate a function that expects to take the next parameter. This is the idea behind currying [Haskell-wiki]. Indeed, if the type of add 2 is:
Prelude> :t add 2
add 2 :: Int -> Int
It is a function that expects the following parameter. It is possible that this will clash with another function that expects an Int, but then you will get a similar exception except that the expected will be a non-function (Int) for example, and the actual type is a function, so something like:
• Couldn't match expected type ‘Int’
with actual type ‘Integer -> t’
Haskell's type system will thus error in case you call a function with too much arguments, or when you use the result of a function with too few arguments.
Note that strictly speaking in Haskell every function only takes one parameter. If you do not provide one, then the outcome is still a function, if you provide one, you make a function call, but that function can produce another function thus expects the next parameter.
The reason that printf can take one, two, or more parameters, is because of the instances of the PrintfType type class. This can be an IO a that will thus then print the result of the formatted string, or a function (PrintfArg a, PrintfType r) => a -> r that thus will take a parameter of the PrintfArg type, and return another PrintfType type. It can thus each time specialize in an extra function if another function is necessary. But this thus emulates a variadic function, where you can pass an arbitrary number of parameters.

Difference in Function typing in Haskell

I've been playing around with basic functions in Haskell, and am a little confused with the difference between the following type declarations for the function f
f :: Integer -> Integer
versus
f :: Integral n => n -> n
So far, I've treated both of these as identical, but I'm sure this isn't true. What is the difference?
Edit: As a response to the first answer, I wanna propose a similar example which more is along the lines of the question I hold.
Consider the following declarations
f :: Num n => n -> n
or
f :: Num -> Num
What functionality does each offer?
Let's rename:
f :: Integer -> Integer
g :: (Integral n) => n -> n
I like to follow a fairly common practice of adding parentheses to the constraint section of the signature. It helps it stand out as different.
f :: Integer -> Integer is simple, it takes an integer and returns another integer.
As for g :: (Integral n) => n -> n: Integral is not a type itself, rather it's more like a predicate. Some types are Integral, others aren't. For example, Int is an Integral type, Double is not.
Here n is a type variable, and it can refer to any type. (Integral n) is a constraint on the type variable, which restricts what types it can refer to. So you could read it like this:
g takes a value of any type n and returns a value of that same type, provided that it is an Integral type.
If we examine the Integral typeclass:
ghci> :info Integral
class (Real a, Enum a) => Integral a where
quot :: a -> a -> a
rem :: a -> a -> a
div :: a -> a -> a
mod :: a -> a -> a
quotRem :: a -> a -> (a, a)
divMod :: a -> a -> (a, a)
toInteger :: a -> Integer
{-# MINIMAL quotRem, toInteger #-}
-- Defined in ‘GHC.Real’
instance Integral Word -- Defined in ‘GHC.Real’
instance Integral Integer -- Defined in ‘GHC.Real’
instance Integral Int -- Defined in ‘GHC.Real’
We can see 3 builtin types which are Integral. Which means that g simultaneously has three different types, depending on how it is used.
g :: Word -> Word
g :: Integer -> Integer
g :: Int -> Int
(And if you define another Integral type in the future, g will automatically work with that as well)
The Word -> Word variant is a good example, since Words cannot be negative. g, when given a positive machine-sized number, returns another positive machine-sized number, whereas f could return any integer, including negative ones or gigantic ones.
Integral is a rather specific class. It's easier to see with Num, which has fewer methods and thus can represent more types:
h :: (Num a) => a -> a
This is also a generalization of f, that is, you could use h where something with f's type is expected. But h can also take a complex number, and it would then return a complex number.
The key with signatures like g's and h's is that they work on multiple types, as long as the return type is the same as the input type.
According to this link the standard instances of the Integral type class are Integer and Int. Integer is a primitive type, and it acts like an unbounded mathematical integer. So given:
f :: Integral n => n -> n
n could be Int or Integer or any "custom" type that you define that is an instance of Integral. The use of type classes allows for type polymorphism.
f :: Num -> Num WILL NOT COMPILE because Num is not a type. Num has kind * -> Constraint and is thus a type constructor whereas f requires an ordinary type or monotype which has kind *, such as Int or Integer (also known as type system primitives). See the haskell wiki for a brief reference/jumping off point about kinds. Haskell has a rich type system with higher-order types, if used correctly it can be an extremely powerful tool i.e. type polymorphism.
f :: Integer -> Integer
f is a function from arbitrary sized integers to arbitrary sized integers.
f' :: Integral n => n -> n
f' is a polymorphic function from type n to type n. Any type n that is member of the class Integral is allowed. Examples for types in Integral are Integer and Int (the integer type with fixed precision).
f'' :: Num n => n -> n
f'' is also a polymorphic function, but this time for class Num. Num is a more generic number type that has more members than Integral, but all types in Integral are also in contained in Num. For f'' n can also be Double.
TL;DR
f :: Integer -> Integer works for one type: Integer.
f :: Integral n => n -> n works for Integer, Int, Word, Int32, Int64, Word8, and any arbitrary user-defined types that implement the Integral type class.
That's the short version. If you only care about one type, it's easier to type-check and more efficient to execute if you specify that one type. If you want multiple types, then the second way is probably the way to do.

Understanding the use of brackets in the all function in Haskell?

I'm trying to wrap my head around the conventions and rules of programming in Haskell. One thing that I find confusing or difficult to understand is the use of brackets (). Can anyone explain to me what it does in the case of the all function?
all :: (a -> Bool) -> [a] -> Bool
all p xs = and [ p x | x <- xs ]
As I understand it, the type of a function shows the type constraints, inputs and outputs. Wouldn't having
all :: [a] -> Bool
Be enough?
What parentheses do here
Parentheses in Haskell serve a purpose that is very similar to most other programming languages: changing precedence of operations and/or grouping terms.
In your case, the fact that (a -> Bool) is wrapped in parentheses shows that the type of the function's first parameter is a -> Bool. If there was no parentheses (i.e. if the signature was all :: a -> Bool -> [a] -> Bool), then the meaning would be that the type of the function's first parameter is a, and the type of the function's second parameter is Bool.
Wouldn't it be enough to have all :: [a] -> Bool?
If that was the signature, then the question would be: what does such function mean? Does it return True when the list is not empty? Or when it's empty? Or when it contains precisely 42 elements? A bad name for a function. Should have named it has42Elements instead of all.
On the other hand, if the function takes the first parameter of type a -> Bool (that is, a function that takes an a and returns a Bool), then the meaning of all would be "check if this function is True for all elements in this list".

Constant's value given by a non-intrinsic function

In Fortran, is there a way to initialize my named constant at compilation time using a function of other constants, other than the intrinsic functions?
I want to calculate a value using my own function and then use this value to declare the size of an array, such as in my attempt below.
integer function factorial(n)
implicit none
integer, intent(in) :: n
integer :: i, ans
ans=1
do i=1,n
ans=ans*i
end do
factorial = ans
end function Factorial
integer function binomial(n,k)
implicit none
integer, intent(in) :: n, k
integer :: factorial
binomial = Factorial(n)/factorial(n-k)/factorial(k)
end function binomial
program main
implicit none
integer, parameter :: m=10, n=3
integer :: binomial
integer, parameter :: sz=binomial(m,n)
complex, dimension(sz) :: hamiltonian
...
end program main
Or do I have have to calculate this value myself and write it explicitly in the code ?
As you seem to know, the Fortran standard prohibits calculations, at compile time, beyond what intrinsic routines are capable of. If you really must make those calculations at compile time then a hack like this might appeal to you:
INTEGER, DIMENSION(20), PARAMETER :: ints = [1,2,3,4,5,6,7,8,9,10, &
11,12,13,14,15,16,17,18,19,20]
INTEGER, PARAMETER :: m=10, n=3
INTEGER, PARAMETER :: sz = PRODUCT(ints(1:m))/PRODUCT(ints(1:m-n))/&
PRODUCT(ints(1:n))
COMPLEX, DIMENSION(sz) :: hamiltonian
This compiles, and executes, correctly. If you confine yourself to 64-bit integers the array ints doesn't need to go larger than 20.
Oh, in passing, don't use size as the name of a parameter, it's already the name of a useful intrinsic function.
Then again, you could just compute the factorials yourself and write:
INTEGER, DIMENSION(20), PARAMETER :: factorial = [1,2,6,24,...]
INTEGER, PARAMETER :: m=10, n=3
INTEGER, PARAMETER :: sz = factorial(m)/factorial(m-n)/factorial(n)
COMPLEX, DIMENSION(sz) :: hamiltonian
and be done with it.

passing 2 arguments to a function in Haskell

In Haskell, I know that if I define a function like this add x y = x + y
then I call like this add e1 e2. that call is equivalent to (add e1) e2
which means that applying add to one argument e1 yields a new function which is then applied to the second argument e2.
That's what I don't understand in Haskell. in other languages (like Dart), to do the task above, I would do this
add(x) {
return (y) => x + y;
}
I have to explicitly return a function. So does the part "yields a new function which is then applied to the second argument" automatically do underlying in Haskell? If so, what does that "hiding" function look like? Or I just missunderstand Haskell?
In Haskell, everything is a value,
add x y = x + y
is just a syntactic sugar of:
add = \x -> \y -> x + y
For more information: https://wiki.haskell.org/Currying :
In Haskell, all functions are considered curried: That is, all functions > in Haskell take just single arguments.
This is mostly hidden in notation, and so may not be apparent to a new
Haskeller. Let's take the function
div :: Int -> Int -> Int
which performs integer division. The expression div 11 2
unsurprisingly evaluates to 5. But there's more that's going on than
immediately meets the untrained eye. It's a two-part process. First,
div 11
is evaluated and returns a function of type
Int -> Int
Then that resulting function is applied to the value 2, and yields 5.
You'll notice that the notation for types reflects this: you can read
Int -> Int -> Int
incorrectly as "takes two Ints and returns an Int", but what it's
really saying is "takes an Int and returns something of the type Int
-> Int" -- that is, it returns a function that takes an Int and returns an Int. (One can write the type as Int x Int -> Int if you
really mean the former -- but since all functions in Haskell are
curried, that's not legal Haskell. Alternatively, using tuples, you
can write (Int, Int) -> Int, but keep in mind that the tuple
constructor (,) itself can be curried.)