I've been learning about uncurrying and applying $ in functions in haskell but I'm still having issues converting an uncurried function to something less mysterious.
The function I'm given is
apple = map $ uncurry $ flip ($)
and I realize that this takes a list of tuples and applies to corresponding function in the tuple to the variable inside. So I'm trying to rewrite it as
apple ls = foldr function _ ls
where function (a,b) c = (uncurry b) (a,c)
I get the error for _ as a parse error and I have no idea which starting point to use. I need to make this polymorphic and I'm realizing that this most likely will not be the way to make it less mysterious. Any ideas? They'd be greatly appreciated
Apple has the type
apple :: [(a, a->b)] -> [b]
We could rewrite it as
apple ls = map (\(a, f) -> f a) ls
So writing this with foldr is very doable,
apple ls = foldr (\(a, f) rest -> f a : rest) [] ls
Or, we can rewrite this to pointfree
apple = foldr ( (:) . (uncurry . flip $ ($)) ) []
The reason for the parse error is that _ is the special syntax for "variables I don't care about". This let's you write things like
foo _ _ _ _ a = a
And not get an error about repeated variables. Basically we just filled in _ with the starting empty list and fixed function so that it appends to c rather than trying to apply it to a.
If I wanted to write this in the clearest way possible, then the original
apple = map . uncurry . flip $ ($)
Is quite nice.
The key for understanding is removing complexity.
Thus I would suggest you deal with a single tuple first. Write the following function:
tapp :: (a, a ->b) -> b
in terms of ($) and flip and uncurry.
(To make it even easier, you could first do it for a tuple (a -> b, a) first).
Next, make clear to yourself how map works: If you have a function f :: (a -> b), then map f will be a function [a] -> [b]. Hence map tapp does what you want.
You can now replace tapp in map (tapp) by it's definition (this are the benefits of referential transparency).
And this should take you back to your original expression. More or less so, because, for example:
f $ g h
can be written
f (g h)
or
(f . g) h
Related
So, I'm trying to implement a polyvariadic ZipWithN as described here. Unfortunately, Paczesiowa's code seems to have been compiled with outdated versions of both ghc and HList, so in the process of trying to understand how it works, I've also been porting it up to the most recent versions of both of those (ghc-7.8.3 and HList-0.3.4.1 at this time). It's been fun.
Anyways, I've run into a bug that google isn't helping me fix for once, in the definition of an intermediary function curryN'. In concept, curryN' is simple: it takes a type-level natural number N (or, strictly speaking, a value of that type), and a function f whose first argument is an HList of length N, and returns an N-ary function that takes makes an HList out of its first N arguments, and returns f applied to that HList. It's curry, but polyvariadic.
It uses three helper functions/classes:
The first is ResultType/resultType, as I've defined here. resultType takes a single function as an argument, and returns the type of that function after applying it to as many arguments as it will take. (Strictly speaking, again, it returns an undefined value of that type).
For example:
ghci> :t resultType (++)
resultType (++) :: [a]
ghci> :t resultType negate
resultType negate :: (ResultType a result, Num a) => result
(The latter case because if a happens to be a function of type x -> y, resultType would have to return y. So it's not perfect applied to polymorphic functions.)
The second two are Eat/eat and MComp/mcomp, defined together (along with curryN') in a single file (along with the broken curryN') like this.
eat's first argument is a value whose type is a natural number N, and returns a function that takes N arguments and returns them combined into an HList:
ghci> :t eat (hSucc (hSucc hZero))
eat (hSucc (hSucc hZero)) :: x -> x1 -> HList '[x, x1]
ghci> eat (hSucc (hSucc hZero)) 5 "2"
H[5, "2"]
As far as I can tell it works perfectly. mcomp is a polyvariadic compose function. It takes two functions, f and g, where f takes some number of arguments N. It returns a function that takes N arguments, applies f to all of them, and then applies g to f. (The function order parallels (>>>) more than (.))
ghci> :t (,,) `mcomp` show
(,,) `mcomp` show :: (Show c, Show b, Show a) => a -> b -> c -> [Char]
ghci> ((,,) `mcomp` show) 4 "str" 'c'
"(4,\"str\",'c')"
Like resultType, it "breaks" on functions whose return types are type variables, but since I only plan on using it on eat (whose ultimate return type is just an HList), it should work (Paczesiowa seems to think so, at least). And it does, if the first argument to eat is fixed:
\f -> eat (hSucc (hSucc hZero)) `mcomp` f
works fine.
curryN' however, is defined like this:
curryN' n f = eat n `mcomp` f
Trying to load this into ghci, however, gets this error:
Part3.hs:51:1:
Could not deduce (Eat n '[] f0)
arising from the ambiguity check for ‘curryN'’
from the context (Eat n '[] f,
MComp f cp d result,
ResultType f cp)
bound by the inferred type for ‘curryN'’:
(Eat n '[] f, MComp f cp d result, ResultType f cp) =>
Proxy n -> (cp -> d) -> result
at Part3.hs:51:1-29
The type variable ‘f0’ is ambiguous
When checking that ‘curryN'’
has the inferred type ‘forall f cp d result (n :: HNat).
(Eat n '[] f, MComp f cp d result, ResultType f cp) =>
Proxy n -> (cp -> d) -> result’
Probable cause: the inferred type is ambiguous
Failed, modules loaded: Part1.
So clearly eat and mcomp don't play as nicely together as I would hope. Incidentally, this is significantly different from the kind of error that mcomp (+) (+1) gives, which complains about overlapping instances for MComp.
Anyway, trying to find information on this error didn't lead me to anything useful - with the biggest obstacle for my own debugging being that I have no idea what the type variable f0 even is, as it doesn't appear in any of the type signatures or contexts ghci infers.
My best guess is that mcomp is having trouble recursing through eat's polymorphic return type (even though what that is is fixed by a type-level natural number). But if that is the case, I don't know how I'd go about fixing it.
Additionally (and bizarrely to me), if I try to combine Part1.hs and Part2.hs into a single file, I still get an error...but a different one
Part3alt.hs:59:12:
Overlapping instances for ResultType f0 cp
arising from the ambiguity check for ‘curryN'’
Matching givens (or their superclasses):
(ResultType f cp)
bound by the type signature for
curryN' :: (MComp f cp d result, Eat n '[] f, ResultType f cp) =>
Proxy n -> (cp -> d) -> result
at Part3alt.hs:(59,12)-(60,41)
Matching instances:
instance result ~ x => ResultType x result
-- Defined at Part3alt.hs:19:10
instance ResultType y result => ResultType (x -> y) result
-- Defined at Part3alt.hs:22:10
(The choice depends on the instantiation of ‘cp, f0’)
In the ambiguity check for:
forall (n :: HNat) cp d result f.
(MComp f cp d result, Eat n '[] f, ResultType f cp) =>
Proxy n -> (cp -> d) -> result
To defer the ambiguity check to use sites, enable AllowAmbiguousTypes
In the type signature for ‘curryN'’:
curryN' :: (MComp f cp d result, Eat n [] f, ResultType f cp) =>
Proxy n -> (cp -> d) -> result
Failed, modules loaded: none.
Again with the mysterious f0 type variable. I'll admit that I'm a little bit over my head here with all this typehackery, so if anyone could help me figure out what exactly the problem here is, and, more importantly, how I can fix it (if it is, hopefully, possible), I'd be incredibly grateful.
Final note: the reasons that the two files here are called Part1 and Part3 is that Part2 contains some auxiliary functions used in zipWithN, but not curryN'. For the most part they work fine, but there are a couple of oddities that I might ask about later.
Is it possible to remove the duplicates (as in nub) from a list of functions in Haskell?
Basically, is it possible to add an instance for (Eq (Integer -> Integer))
In ghci:
let fs = [(+2), (*2), (^2)]
let cs = concat $ map subsequences $ permutations fs
nub cs
<interactive>:31:1:
No instance for (Eq (Integer -> Integer))
arising from a use of `nub'
Possible fix:
add an instance declaration for (Eq (Integer -> Integer))
In the expression: nub cs
In an equation for `it': it = nub cs
Thanks in advance.
...
Further, based on larsmans' answer, I am now able to do this
> let fs = [AddTwo, Double, Square]
> let css = nub $ concat $ map subsequences $ permutations fs
in order to get this
> css
[[],[AddTwo],[Double],[AddTwo,Double],[Square],[AddTwo,Square],[Double,Square],[AddTwo,Double,Square],[Double,AddTwo],[Double,AddTwo,Square],[Square,Double],[Square,AddTwo],[Square,Double,AddTwo],[Double,Square,AddTwo],[Square,AddTwo,Double],[AddTwo,Square,Double]]
and then this
> map (\cs-> call <$> cs <*> [3,4]) css
[[],[5,6],[6,8],[5,6,6,8],[9,16],[5,6,9,16],[6,8,9,16],[5,6,6,8,9,16],[6,8,5,6],[6,8,5,6,9,16],[9,16,6,8],[9,16,5,6],[9,16,6,8,5,6],[6,8,9,16,5,6],[9,16,5,6,6,8],[5,6,9,16,6,8]]
, which was my original intent.
No, this is not possible. Functions cannot be compared for equality.
The reason for this is:
Pointer comparison makes very little sense for Haskell functions, since then the equality of id and \x -> id x would change based on whether the latter form is optimized into id.
Extensional comparison of functions is impossible, since it would require a positive solution to the halting problem (both functions having the same halting behavior is a necessary requirement for equality).
The workaround is to represent functions as data:
data Function = AddTwo | Double | Square deriving Eq
call AddTwo = (+2)
call Double = (*2)
call Square = (^2)
No, it's not possible to do this for Integer -> Integer functions.
However, it is possible if you're also ok with a more general type signature Num a => a -> a, as your example indicates! One naïve way (not safe), would go like
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE NoMonomorphismRestriction #-}
data NumResLog a = NRL { runNumRes :: a, runNumResLog :: String }
deriving (Eq, Show)
instance (Num a) => Num (NumResLog a) where
fromInteger n = NRL (fromInteger n) (show n)
NRL a alog + NRL b blog
= NRL (a+b) ( "("++alog++ ")+(" ++blog++")" )
NRL a alog * NRL b blog
= NRL (a*b) ( "("++alog++ ")*(" ++blog++")" )
...
instance (Num a) => Eq (NumResLog a -> NumResLog a) where
f == g = runNumResLog (f arg) == runNumResLog (g arg)
where arg = NRL 0 "THE ARGUMENT"
unlogNumFn :: (NumResLog a -> NumResLog c) -> (a->c)
unlogNumFn f = runNumRes . f . (`NRL`"")
which works basically by comparing a "normalised" version of the functions' source code. Of course this fails when you compare e.g. (+1) == (1+), which are equivalent numerically but yield "(THE ARGUMENT)+(1)" vs. "(1)+(THE ARGUMENT)" and thus are indicated as non-equal. However, since functions Num a => a->a are essentially constricted to be polynomials (yeah, abs and signum make it a bit more difficult, but it's still doable), you can find a data type that properly handles those equivalencies.
The stuff can be used like this:
> let fs = [(+2), (*2), (^2)]
> let cs = concat $ map subsequences $ permutations fs
> let ncs = map (map unlogNumFn) $ nub cs
> map (map ($ 1)) ncs
[[],[3],[2],[3,2],[1],[3,1],[2,1],[3,2,1],[2,3],[2,3,1],[1,2],[1,3],[1,2,3],[2,1,3],[1,3,2],[3,1,2]]
I want to write a function that can list a directory recursively in breadth-first in Haskell.
As you can see I need a function that can convert a (a -> IO b) to a IO (a->b). Simple as it seems, I can't make it. And I want to know how to do or whether it is possible.
dirElem :: FilePath -> IO [FilePath]
dirElem dirPath = do
getDirectoryContents'' <- theConvert getDirectoryContents'
return $ takeWhile (not.null) $ iterate (concatMap getDirectoryContents'') [dirPath] where
getDirectoryContents' dirPath = do
isDir <- do doesDirectoryExist dirPath
if isDir then dirContent else return [] where
dirContent = do
contents <- getDirectoryContents dirPath
return.(map (dirElem</>)).tail.tail contents
theConvert :: (a -> IO b) -> IO (a -> b)
theConvert = ??????????
This cannot be done. The reason is that the function can use its argument of type a to determine what IO action is executed. Consider
action :: Bool -> IO String
action True = putStrLn "Enter something:" >> getLine
action False = exitFailure
Now if you'd convert it somehow to IO (Bool -> String) and evaluate this action, what should happen? There is no solution. We cannot decide if we should read a string or exit, because we don't know the Bool argument yet (and we may never know it, if the resulting function isn't called on an argument).
John's answer is a bad idea. It simply lets the IO action escape into pure computations, which will make your life miserable and you'll lose Haskell's referential transparency! For example running:
main = unsafe action >> return ()
will do nothing even though the IO action was called. Moreover, if we modify it a bit:
main = do
f <- unsafe action
putStrLn "The action has been called, calling its pure output function."
putStrLn $ "The result is: " ++ f True
you'll see that the action that asks for an input is executed in a pure computation, inside calling f. You'll have no guarantee when (if at all) the action is executed!
Edit: As others pointed out, it isn't specific just to IO. For example, if the monad were Maybe, you couldn't implement (a -> Maybe b) -> Maybe (a -> b). Or for Either, you couldn't implement (a -> Either c b) -> Either c (a -> b). The key is always that for a -> m b we can choose different effects depending on a, while in m (a -> b) the effect must be fixed.
You cannot do it in a pure way in general, but if you can enumerate all the argument values you can perform all the IO upfront and return a pure function. Something like
cacheForArgs :: [a] -> (a -> IO b) -> IO (a -> b)
cacheForArgs as f = do
bs <- mapM f as
let abs = zip as bs
return $ \ a -> fromMaybe (error "argument not cached") $ lookup a abs
cacheBounded :: (Enum a, Bounded a) => (a -> IO b) -> IO (a -> b)
cacheBounded = cacheForArgs [minBound .. maxBound]
But this function doesn't really help you much in your use case.
You cannot create such function in a safe manner. Say we have f :: a -> IO b and g = theConvert f :: IO (a -> b). They are two very different functions f is an function that takes an argument of type a and returns an IO action with result b, where the io-action may depend on the argument given. g on the other hand is an IO action with as result a function a->b, the io-action cannot depend on any argument.
Now to illustrate this problem lets lookat
theConvert putStr :: IO (String -> ())
Now what should it do when its run, it can certainly not print a given argument as it has no argument. Thus unlike putStr it can only do one action and then return some function of type String -> (), which has only one option const () (assuming no use of error or undefined).
Just as a side not, the other way around can be done, it adds the notion that the resulting action depends on the argument, while it actually does not. It can be written as
theOtherConvert :: IO (a -> b) -> (a -> IO b)
theOtherConvert m x = m >>= \f -> return $ f x
Though it works on any monad, or in applicative form theOtherConvert m x = m <*> pure x.
Petr Pudlák's answer is excellent, but I feel it can be generalized by abstracting away from IO, and looking at it from the point of view of the Applicative and Monad type classes.
Consider the types of the "combining" operations from Applicative and Monad:
(<*>) :: Applicative m => m (a -> b) -> m a -> m b
(>>=) :: Monad m => m a -> (a -> m b) -> m b
So you could say that your type a -> IO b is "monadic" while IO (a -> b) is "applicative"—meaning that you need monadic operations to compose types that look like a -> IO b, but only applicative operations for IO (a -> b)
There's a well-known intuitive statement of the "power" difference between Monad and Applicative:
Applicative computations have a fixed static structure; what actions will be executed, what order they will be executed in, and the manner in which the results will be combined is known ahead of time.
Monadic computations don't have such a fixed static structure; a monadic computation can examine the result value from one of its subactions and then choose between different structures at execution time.
Petr's answer is a concrete illustration of this point. I'll repeat his definition of action:
action :: Bool -> IO String
action True = putStrLn "Enter something:" >> getLine
action False = exitFailure
Suppose we have foo :: IO Bool. Then when we write foo >>= action to bind action's parameter to foo's result, the resulting computation does nothing less than what my second bullet point describes; it examines the result of executing foo and chooses between alternative actions based on its value. This is precisely one of the things that Monad allows you to do that Applicative doesn't. You can't Petr's action into IO (Bool -> String) unless at the same time you predetermine which branch would be taken.
Similar remarks apply to augustss's response. By requiring that a list of values be specified ahead of time, what it's doing is making you choose which branches to take ahead of time, taking them all, and then allowing you to pick between their results.
Instead of fmap, which applies a function to a value-in-a-functor:
fmap :: Functor f => (a -> b) -> f a -> f b
I needed a function where the functor has a function and the value is plain:
thing :: Functor f => f (a -> b) -> a -> f b
but I can't find one.
What is this pattern called, where I apply a function-in-a-functor (or in an applicative, or in a monad) to a plain value?
I've implemented it already, I just don't quite understand what I did and why there wasn't already such a function in the standard libraries.
You don't need Applicative for this; Functor will do just fine:
apply f x = fmap ($ x) f
-- or, expanded:
apply f x = fmap (\f' -> f' x) f
Interestingly, apply is actually a generalisation of flip; lambdabot replaces flip with this definition as one of its generalisations of standard Haskell, so that's a possible name, although a confusing one.
By the way, it's often worth trying Hayoo (which searches the entirety of Hackage, unlike Hoogle) to see what names a function is often given, and whether it's in any generic package. Searching for f (a -> b) -> a -> f b, it finds flip (in Data.Functor.Syntax, from the functors package) and ($#) (from the synthesizer package) as possible names. Still, I'd probably just use fmap ($ arg) f at the use site.
As Niklas says, this is application in some applicative functor to a lifted value.
\f a -> f <*> pure a
:: Applicative f => f (a -> b) -> a -> f b
or more generally (?), using Category (.)
\f a -> f . pure a
:: (Applicative (cat a), Category cat) => cat b c -> b -> cat a c
A while ago, I asked a question about $, and got useful answers -- in fact, I thought I understood how to use it.
It seems I was wrong :(
This example shows up in a tutorial:
instance Monad [] where
xs >>= f = concat . map f $ xs
I can't for the life of me see why $ was used there; ghci isn't helping me either, as even tests I do there seem to show equivalence with the version that would simply omit the $. Can someone clarify this for me?
The $ is used here because it has lower precedence than normal function application.
Another way to write this code is like so:
instance Monad [] where
xs >>= f = (concat . map f) xs
The idea here is to first construct a function (concat . map f) and then apply it to its argument (xs). As shown, this can also be done by simply putting parenthesis around the first part.
Note that omitting the $ in the original definition is not possible, it will result in a type error. This is because the function composition operator (the .) has a lower precedence than normal function application effectively turning the expression into:
instance Monad [] where
xs >>= f = concat . (map f xs)
Which doesn't make sense, because the second argument to the function composition operator isn't a function at all. Although the following definition does make sense:
instance Monad [] where
xs >>= f = concat (map f xs)
Incidentally, this is also the definition I would prefer, because it seems to me to be a lot clearer.
I'd like to explain why IMHO this is not the used style there:
instance Monad [] where
xs >>= f = concat (map f xs)
concat . map f is an example of so-called pointfree-style writing; where pointfree means "without the point of application". Remember that in maths, in the expression y=f(x), we say that f is applied on the point x. In most cases, you can actually do a final step, replacing:
f x = something $ x
with
f = something
like f = concat . map f, and this is actually pointfree style.
Which is clearer is arguable, but the pointfree style gives a different point of view which is also useful, so sometimes is used even when not exactly needed.
EDIT: I have replaced pointless with pointfree and fixed some examples, after the comment by Alasdair, whom I should thank.
The reason $ is used here is doe to the type signature of (.):
(.) :: (b -> c) -> (a -> c) -> a -> c
Here we have
map f :: [a] -> [[b]]
and
concat :: [[b]] -> [b]
So we end up with
concat . map f :: [a] -> [b]
and the type of (.) could be written as
(.) :: ([[b]] -> [b]) -> ([a] -> [[b]]) -> [a] -> [b]
If we were to use concat . map f xs, we'd see that
map f xs :: [[b]]
And so cannot be used with (.). (the type would have to be (.) :: (a -> b) -> a -> b