Dot Versus Dollar symbol - haskell

print $ concat ["abc", "bde"]
prints
abcbde
whereas,
print . concat ["abc", "bde"]
The error thrown in second case is,
Couldn't match expected type ‘a -> b0’ with actual type ‘[Char]’
Relevant bindings include
it :: a -> IO () (bound at <interactive>:3:1)
Possible cause: ‘concat’ is applied to too many arguments
. (function-composition operator) is used because i thought it will take the output of concat function and pass it to the preceding function print? What is wrong in the code?

Just precedence, really; this will work fine:
(print . concat) ["abc", "bde"]
. composes two functions to create a new function, whereas $ is just a way of avoiding parentheses in this context.

Related

Why is (.) called infix as just . rather than `(.)`

I learned that functions can be invoked in two ways; prefix and infix. For example, say I've created this function:
example :: [Char] -> [Char] -> [Char]
example x y = x ++ " " ++ y
I can call it prefix like so:
example "Hello" "World"
or infix like so:
"Hello" `example` "World"
Both of which will result in the list of chars representing a string "Hello World".
However, I am now learning about function composition, and have come across the function defined like so:
(.) :: (b -> c) -> (a -> b) -> a -> c
So, say I was wanting to compose negate with multiplication by three. I would write the prefix invocation like:
negateComposedWithMultByThree = (.) negate (*3)
And the infix invocation like:
negateComposedWithMultByThree = negate `(.)` (*3)
But, whilst the prefix invocation compiles, the infix invocation does not and instead gives me the error message:
error: parse error on input `('
It seems, in order to call compose infix, I need to omit the brackets and call it like so:
negateComposedWithMultByThree = negate . (*3)
Can anyone shed any light on this? Why does "Hello" `example` "World" whilst negate `(.)` (*3) does not?
In addition, if I try to make my own function with a signature like this:
(,) :: Int -> Int
(,) x = 1
It does not compile, with the error:
"Invalid type signature (,) : ... Should be of form :: "
There's nothing deep here. There's just two kinds of identifiers that have different rules about how they're parsed: by-default-infix, and by-default-prefix. You can tell which is which, because by-default-infix identifiers contain only punctuation, while by-default-prefix identifiers contain only numbers, letters, apostrophes, and underscores.
Recognizing that the default isn't always the right choice, the language provides conversions away from the default behavior. So there are two separate syntax rules, one that converts a by-default-infix identifier to prefix (add parentheses), and one that converts a by-default-prefix identifier to infix (add backticks). You can not nest these conversions: a by-default-infix identifier converted to prefix form is not a by-default-prefix identifier.
That's it. Nothing fundamentally interesting -- all of them become just function applications once parsed -- it's just syntax sugar.

Haskell chain of functions

I have a composition of functions, many of them operators, to raise a constant to the power of a constant minus the size of the ith set in a list. Here's my code:
(k^).(n-).size.(phi !!) i
When I tried it on a test case I got
<interactive>:64:16-25:
Couldn't match expected type ‘a -> Set a0’
with actual type ‘Set a1’
Relevant bindings include
it :: a -> c (bound at <interactive>:64:1)
Possible cause: ‘phi !!’ is applied to too many arguments
In the second argument of ‘(.)’, namely ‘(phi !!) 3’
In the second argument of ‘(.)’, namely ‘size . (phi !!) 3’
However,
(k^)$(n-)$size$(phi !!)$i
works. What's wrong? Why does composition not work but application work? Also, is composing the operators in parentheses the most idiomatic way to do it? It feels weird.
Rather than f . g . h x, you want f . g . h $ x: the former calls h x immediately and then composes that, as a function, with f and g The latter composes together f, g, and h into a new function and then calls that on i.
Note that you can use parenthesis to group function compositions,
((k^).(n-).size.(phi !!)) i should work.

Create concatenate function in Haskell: [String] -> String

I'm having a lot of trouble getting this function to work:
concatenate :: [String] -> String
It is designed to simply take a list of strings and return a single string that is the result of the concatenations of each element of the list from head to tail. I'm trying to stay within the map, foldl, and foldr functions. I feel like I know what the concept of these functions do well enough, but the most common problem I'm running into is that I'm having a conflict of types. GHC will expect a [Char] for example, and I'll put in code that is apparently trying to use a [[Char]] without me knowing it.
For example: concatenate (x:xs) = foldr (++) x (concatenate xs)
And I get the following compile error:
Couldn't match type `Char' with `[Char]'
Expected type: [[Char]]
Actual type: String
In the return type of a call of `concatenate'
In the third argument of `foldr', namely `(concatenate xs)'
In the expression: foldr (++) x (concatenate xs)
I'm very new to Haskell, so please feel free to laugh. Harshness is expected, and welcomed, as long as an explanation fit for a newbie is also included. Thank you for any and all help.
You actually don't need the recursive call there. The function foldr already simulates a recursive call. All you need to do is use:
concatenate :: [String] -> String
concatenate ls = foldr (++) "" ls
And remember that there's a concat function already, which is more generic, as it works on any list of list (as opposed to simply list of strings).

Using the haskell map function with a string

I'm trying to use the map function in haskell
I've got this:
lexi :: String -> [[String]]
lexi x = map (words.lines) x
I want to be able to put a string in to x, so it can be run like this
lexi ("string here")
But get the error
Couldn't match type ‘[Char]’ with ‘Char’
Expected type: String -> String
Actual type: String -> [String]
In the second argument of ‘(.)’, namely ‘lines’
In the first argument of ‘map’, namely ‘(words . lines)’
Couldn't match type ‘Char’ with ‘[Char]’
Expected type: [String]
Actual type: String
In the second argument of ‘map’, namely ‘x’
In the expression: map (words . lines) x
I know that if I use
lexi = map (words.lines)
it works fine when I run lexi ("string here"), but need the variable to use later on
Could some please explain why this doesn't work and how to fix it?
Thank you :)
This answer refers to an old version of the question.
So let's get this quite clear (please always add the type signature of all functions you're talking about!)
function :: Char -> [String]
Well, then the type of map function is [Char] -> [[String]], i.e. String -> [[String]]. But you want the result to be only [String], not a triply-nested list. You probably want to join the lists of two levels together; in general the function to use for list-joining purposes is concat (or more generally, join from the Control.Monad module). In this case, you have two different options:
Join the result of each call to function. I.e., instead of mapping function alone, you map join . function, which has type Char -> String. Mapping that has the desired type String -> [String].
lexi = map $ join . function
Join the final result of the mapping, i.e. lexi = join . map function. This combination of mapping and joining the results is actually an extremely common task, it has a special operator: monadic bind!
lexi x = x >>= function
New version
So we know that
words, lines :: String -> [String]
thus words . lines can not work, because you're trying to feed a list of strings into a function that only accepts a single string. What you can of course do though is map words over the result, i.e. map words . lines. That has in fact the correct signature and probably does just what you want.

Haskell: type mismatch when chaining getPermissions and searchable?

I'm a bit of a newbie with haskell and am trying to understand why the following code seems to fail.
Why can I not write:
getPermissions "." >>= searchable
but I can write:
do { p <- getPermissions "."; return $ searchable p }
The former fails with the following error:
<interactive>:65:24:
Couldn't match type `Bool' with `IO b0'
Expected type: Permissions -> IO b0
Actual type: Permissions -> Bool
In the second argument of `(>>=)', namely `searchable'
In the expression: getPermissions "." >>= searchable
In an equation for `it': it = getPermissions "." >>= searchable
My understanding is that (>>=) operates similarly to (<-) effectively passing the unwrapped value in the monad to a non-monad function.
What am I not understanding correctly? And how could one chain/compose getPermissions and searchable together concisely?
Many thanks in advance for your assistance!
#Arjan's comment above helped me get a better sense of what's going on. And some additional exploration on my part seemed to solidify the solution.
As mentioned in my second comment above, I seem to have overlooked the return type of the function used in the rhs of the bind (>>=). Since searchable returns a Bool, it doesn't fully qualify as the rhs' type which needs to be some type wrapped in IO, per the error message I saw above (IO b0). By promoting searchable's Bool return type using return I satisfy >>='s rhs type.
#Arjan's code in his comment also gives a concise form I was looking for:
getPermissions "." >>= (return . searchable)
Many thanks!

Resources