Attempting to model operators for Integrated Dynamics - haskell

Integrated Dynamics is a Minecraft mod that uses lazy operators with currying, and acts very similarly to Haskell. I've been writing functions that have the same signature though do not perform anything to try and more easily explore combining the operators. An example is itemName :: Item -> String with itemName _ = "".This is to give in ghci :t itemName as Item -> String.
I've tried to make a couple slightly more complicated ones such as
itemListCount :: (Num c) => [a] -> b -> c
itemListCount _ _ = 0
I'd like to see the signature of this if I pipe it directly with greater than or less than, expecting to see something like [a] -> b -> c -> d. a List, an Item(custm data type) an integer and return a boolean. when calling with :t (lessThan . itemListCount) This gives error:
Couldn't match type 'b0 -> Integer' with 'Int'.
Expected type: [a] -> Int
Actual type: [a] -> b0 -> Integer
Is this because I'm calling it with :t that it's trying to evaluate instead of combining the functions?

(lessThan . itemListCount) is the same as \x -> lessThan (itemListCount x). It's a function, which takes one value, then calls itemListCount with this value, and then calls lessThan with whatever itemListCount returned.
itemListCount's type is (ignoring the Num constraint) [a] -> b -> c. It is a function which takes a list of any type, and then returns a function which takes any type as input and returns any number type as output.
So in \x -> lessThan (itemListCount x), x should be a list of any type, and (itemListCount x) is a function which takes any type as input and returns any number type as output. Presumably, this is not a valid argument for lessThan.

Related

Higher Order Functions evaluation

Create a high-order function in Haskell that takes in another function. That second function takes in a list and evaluates to each index to be true or false. The high order function should evaluate to true if the second function evaluates to true for at least 2 indexes in the list
This is what I have so far
Bool _ _ = []
Bool f (x y :xs) = f x y : Bool f xs
Split your task into subtasks:
Create a high-order function in Haskell that takes in another function.
higherOrder :: (a -> b) -> Bool
higherOrder f = undefined -- a higher order function that takes
-- in another function
We have not learned anything about the type of the passed function, which is why we use the placeholder a -> b. This will be change later, once we learn more about f.
That second function takes in a list and evaluates to each index to be true or false.
This function is passed in. You don't need to implement it, it will be provided as an argument. You do however need to know its type signature, in this case
f :: [a] -> [Bool] -- a function taking a list of any type
-- ([a]), evaluating it to a list of booleans
-- example usage
f [1, 2, 3] == [True, False, True]
Which we use to update the type of our higherOrder
higherOrder :: ([a] -> [Bool]) -> Bool
The high order function should evaluate to true if the second function evaluates to true for at least 2 indexes in the list
You could replace this step with a simpler step: Write a function atLeastTwo :: [Bool] -> Bool, that takes a list of Booleans ([Bool]) and returns True if at least two indexes' values are true.
atLeastTwo :: [Bool] -> Bool
atLeastTwo xs = undefined
Maybe you can implement atLeastTwo by filtering the list, keeping only True values and then counting its length. You might find filter :: (a -> [Bool]) -> [a] -> [a] and length :: [a] -> Int1 useful.
Putting it all together you will discover that the task description is not clear. It does not talk about the list that is passed to higherOrder. In your case it probably should have been passed as a second parameter (xs) so we update higherOrder again to
higherOrder :: ([a] -> [Bool]) -> [a] -> Bool
higherOrder f xs = undefined
Proposal for an updated assignment
A more natural problem would be, where the passed function processes a list element (a -> Bool) instead of a list ( [a] -> [Bool]), and would read:
[Updated/alternative assignment: replacing ([a] -> [Bool]) with (a -> Bool).]
Implement a (higher-order) function atLeastTwoTrues :: (a -> Bool) -> [a] -> Bool. The first argument being passed to atLeastTwoTrues should be a function that can evaluate a value to either True or False. The second argument is a list of values. Your function should return True if and only if at least two elements of the passed list evaluate to True using the first argument.
This would avoid some ambiguity but is a different problem.
Good luck and enjoy your Haskell journey. It is difficult at the start. It has been for all of us. Don't give up, because once you start to master it, you will enjoy it.
1This is actually not the complete truth since length works with more data types than just lists and has a more general type.
Prelude> :t length
length :: Foldable t => t a -> Int

Understanding Data.Function.on type signature

I'm still a beginner when it comes to Haskell syntax and functional programming languages so when I look at the type declaration for Data.Function.on which is on :: (b -> b -> c) -> (a -> b) -> a -> a -> c, my interpretation is that it takes four parameters: (b -> b -> c), (a -> b), a, a, and returns c. However, when I look at the general use syntax for Data.Function.on which is (*) `on` f = \x y -> f x * f y, it is only taking two function parameters, not four, so how does the type signature relate to the usage syntax?
my interpretation is that it takes four parameters
All Haskell functions take one argument. Some of them just return other functions.
The best way to look at the signature for on is as a higher-order function: (b -> b -> c) -> (a -> b) -> (a -> a -> c). This says "if you give me a binary operator that takes bs and gives a c and a way to get bs from as, I will give you a binary operator that takes as and gives a c". You can see this in the definition:
(*) `on` f = \x y -> f x * f y
The Haskell arrow for function types hides a simple but clever idea. You have to think of -> as an operator, like + and -, but for types. It takes two types as arguments and gives you a new type consisting of a function. So in
Int -> String
You have the types Int and String, and you get a function from an Int to a String.
Just like any other operator, you need a rule for a chain of them. If you think of -, what does this mean?
10 - 6 - 4
Does it mean (10 - 6) - 4 = 0, or does it mean 10 - (6 - 4) = 8? The answer is the first one, which is why we say that - is "left associative".
The -> operator is right associative, so
foo :: Int -> String -> String
actually means
foo :: Int -> (String -> String)
Think about what this means. It means that foo doesn't take 2 arguments and return a result of type String, it actually takes 1 argument (the Int) and returns a new function that takes the second argument (the String) and returns the final String.
Function application works the same way, except that is left associative. So
foo 15 "wibble"
actually means
(foo 15) "wibble"
So foo is applied to 15 and returns a new function which is then applied to "wibble".
This leads to a neat trick: instead of having to provide all the parameters when you call a function (as you do in just about every other programming language), you can just provide the first one or the first few, and get back a new function that expects the rest of the parameters.
This is what is happening with on. I'll use a more concrete version where 'f' is replaced by 'length'.
(*) on length
you give on its first two parameters. The result is a new function that expects the other two. In types,
on :: (b -> b -> c) -> (a -> b) -> a -> a -> c
In this case (*) has type Num n => n -> n -> n (I'm using different letters to make this less confusing), so that is matched with the type of the first argument to on, leading to the conclusion that if type b is substitued by n then type c must be as well, and and must also be a Num instance. Therefore length must return some numeric type. As it happens the type of length is [d] -> Int, and Int is an instance of Num, so that works out. So at the end of this you get:
(*) `on` length :: [d] -> [d] -> Int
As an intuitive aid, I read this as "if you give me a comparator of type b, and a way to extract values of type b from values of type a, I will give you a comparator of type a".
E.g. if a is some composite data type and b is some numerical attribute of these data values, you can express the idea of sorting these composite data types by using Data.Function.on.

Check if a string contains a certain character

I need to check if my string contain a specific character.
I tried this:
charFound :: Char -> String -> Bool
charFound c s = filter(\x -> x == c) s
But it gives me:
Couldn't match expected type Bool with actual type [Char]
I know that filter:
returns a list constructed from members of a list (the second argument) fulfilling a condition given by the first argument.
How could I reach the goal and return a bool instead of a list?
For your purpose, you could use the function elem :: Eq a => a -> [a] -> Bool from prelude. It does exactly what it says on the label. To implement this function, I would use something like this:
elem = any . (==)
or even more elementary:
elem x = foldr ((||) . (x ==)) False
Notice that due to the short-circuit behaviour of (||) this also works with infinite lists as long as x is found.
The type of filter is (a -> Bool) -> [a] -> [a].
You have supplied the first argument which has type Char -> Bool (which is correct), then the second argument which is String (that's [Char]) which is correct, so the type of filter (\x -> x == c) s is [Char].
But the type signature you have provided says the function returns a Bool, which doesn't match the actual type returned.
You probably want to use any instead of filter. It's type is (a -> Bool) -> [a] -> Bool.
There's also an all function that returns True if and only if all elements of the list satisfy the predicate passed. You may also consider the functions or and and that given a [Bool] compute the disjunction or conjunction of the values. So any f = or . map f and all f = and . map f.
For all list-related functions see the Data.List module.

Understanding Haskell types [duplicate]

This question already has answers here:
Understanding Haskell Type Signatures
(3 answers)
Closed 8 years ago.
I need to understand how types works and can be interpreted.
For example, if we take map function we have map :: (a -> b) -> [a] -> [b]
Well, how do I interpret this?
-> is a type constructor for the type of functions. It's a right-associative infix operator, meaning it's grouped together from the right. This means that we can rewrite the type by adding explicit grouping for the functions to the right side.
map :: (a -> b) -> [a] -> [b]
map :: (a -> b) -> ([a] -> [b])
An infix expression for an operator * applied to two arguments, x and y, x * y can be written in prefix notation as (*) a b. We can rewrite the preceding type, starting with the outermost ->, which is the one in the middle.
map :: (->) (a -> b) ([a] -> [b])
And we can now translate the last type into English
map :: (->) (a -> b) ([a] -> [b])
map is a function that takes a "(a -> b)" and returns a "([a] -> [b])"
Where we interpret a -> b ~ (->) a b (here ~ means the types are equivalent) as
(->) a b
function that takes an "a" and return a "b"
And interpret [a] -> [b] ~ (->) [a] [b] as
(->) [ a ] [ b ]
function that takes a list of "a"s and returns a list of "b"s
We say "a function from a to b" as shorthand for "a function that takes an a and returns a b"
The as and bs in the type signature are type variables, they can take on any type, which we call polymorphism. Occasionally, you will see this written explicitly in Haskell as forall So, in all we could say:
map is a polymorphic value for all types a and b which is a function that:
takes a function from a to b and
returns a function from a lists of as to a list of bs.
The fact that this signature contains -> tells us it's a function. Whatever comes after the last -> is the return type of the function once fully applied. Let's look at the individual pieces.
(a -> b)
This is the first argument, and it, too is a function. This means that map is a higher-order-function -- it takes a function as one of its arguments. a -> b itself is a function that transforms some value of type a into some value of type b.
[a]
The second argument. The square brackets is special syntax that denotes list. This argument, therefore, is a list with elements of type a.
[b]
The type of the result. Again, a list, but this time with elements of type b.
We can try to reason about this now. Given a function a -> b and a list of a, map seems to be (it really is) a function that transforms that list of as into a list of bs.
Here's an example: map (*2) [1,2,3]. In this case, a is Integer (or some other integer type) and each element is doubled. b, too, is Integer, because (*2) assumes the same return type, so in the case the type variables a and b are the same. This need not be the case; we could have a different function instead of (*2), say show which would have produced a b distinct from a, namely String.
Try them out in ghci. You can type in map show [1,2,3] directly and see the result. You can query the type of the expression by prepending :t to that line.
To learn more, you should look up one of the marvelous starter resources. LYAH has an entire chapter dedicated to the basic understanding of types, and is definitely worth a read!

Understanding Haskell Type Signatures

I am in the process of teaching myself Haskell and I was wondering about the following type signatures:
Prelude> :t ($)
($) :: (a -> b) -> a -> b
Prelude>
How should I interpret (no pun intended) that?
A semi-similar result is also proving to be puzzling:
Prelude> :t map
map :: (a -> b) -> [a] -> [b]
Prelude>
I'll start with map. The map function applies an operation to every element in a list. If I had
add3 :: Int -> Int
add3 x = x + 3
Then I could apply this to a whole list of Ints using map:
> map add3 [1, 2, 3, 4]
[4, 5, 6, 7]
So if you look at the type signature
map :: (a -> b) -> [a] -> [b]
You'll see that the first argument is (a -> b), which is just a function that takes an a and returns a b. The second argument is [a], which is a list of values of type a, and the return type [b], a list of values of type b. So in plain english, the map function applies a function to each element in a list of values, then returns the those values as a list.
This is what makes map a higher order function, it takes a function as an argument and does stuff with it. Another way to look at map is to add some parentheses to the type signature to make it
map :: (a -> b) -> ([a] -> [b])
So you can also think of it as a function that transforms a function from a to b into a function from [a] to [b].
The function ($) has the type
($) :: (a -> b) -> a -> b
And is used like
> add3 $ 1 + 1
5
All it does is take what's to the right, in this case 1 + 1, and passes it to the function on the left, here add3. Why is this important? It has a handy fixity, or operator precedence, that makes it equivalent to
> add3 (1 + 1)
So whatever to the right gets essentially wrapped in parentheses before being passed to the left. This just makes it useful for chaining several functions together:
> add3 $ add3 $ add3 $ add3 $ 1 + 1
is nicer than
> add3 (add3 (add3 (add3 (1 + 1))))
because you don't have to close parentheses.
Well, as said already, $ can be easily understood if you just forget about currying and see it like, say, in C++
template<typename A, typename B>
B dollar(std::function<B(A)> f, A x) {
return f(x);
}
But actually, there is more to this than just applying a function to a value! The apparent similarity between the signatures of $ and map has in fact a pretty deep category-theory meaning: both are examples of the morphism-action of a functor!
In the category Hask that we work with all the time, objects are types. (That is a bit confusionsome, but don't worry). The morphisms are functions.
The most well-known (endo-)functors are those which have an instance of the eponymous type class. But actually, mathematically, a functor is only something that maps both objects to objects and morphisms to morphisms1. map (pun intended, I suppose!) is an example: it takes an object (i.e. type) A and maps it to a type [A]. And, for any two types A and B, it takes a morphism (i.e. function) A -> B, and maps it to the corresponding list-function of type [A] -> [B].
This is just a special case of the functor class signature operation:
fmap :: Functor f => (a->b) -> (f a->f b)
Mathematics doesn't require this fmap to have a name though. And so there can be also the identity functor, which simply assigns any type to itself. And, every morphism to itself:
($) :: (a->b) -> (a->b)
"Identity" exists obviously more generally, you can also map values of any type to themselves.
id :: a -> a
id x = x
And sure enough, a possible implementation is then
($) = id
1Mind, not anything that maps objects and morphisms is a functor... it does need to satisfy the functor laws.
($) is just function application. It gets a function of type a->b, an argument of type a, applies the function and returns a value of type b.
map is a wonderful example for how reading a function type signature helps understanding it. map's first argument is a function that takes a and returns b, and its second argument is a list of type [a].
So map applies a function of type a->b to a list of a values. And the result type is indeed of type [b] - a list of b values!
(a->b)->[a]->[b] can be interpreted as "Accepts a function and a list and returns another list", and also as "Accepts a function of type a->b and returns another function of type [a]->[b]".
When you look at it this way, map "upgrade" f (the term "lift" is often used in this context) to work on lists: if double is a function that doubles an integer, then map double is a function that double every integer in a list.

Resources