I want to create a function apply that takes a function with an arbitrary amount of arguments as well as a list of integers, and returns the result of the function (Where each integer in the list is an argument in order.
I was thinking something like:
apply :: ([Int] -> Int) -> [Int] -> Int
apply f x:xs = apply (f x) xs
apply f [] = f
But I know this won't work because the type signature is wrong - the function doesn't take a list of ints, it just takes some amount of int arguments.
Additionally, when I get to the base case the f argument to apply should actually be an integer, violating the type signature anyway.
Does anyone know how to deal with this sort of problem?
I want to create a function apply that takes a function with an arbitrary amount of arguments as well as a list of integers,
Why do you want to do this? Perhaps your argument structure should be passed as a data structure, but so far you've over constrained the problem to ensure it won't produce an idiomatic Haskell solution.
You can do it with some fancy type classes
{-# LANGUAGE FlexibleInstances #-}
-- for ApplyType (Int -> r)
class ApplyType t where
apply :: t -> [Int] -> Int
instance ApplyType Int where
apply f _ = f
instance (ApplyType r) => ApplyType (Int -> r) where
apply f (x:xs) = apply (f x) xs
main :: IO ()
main = do print $ apply ((+) :: Int->Int->Int) [1, 2]
print $ apply ((\x y z w -> x*y - z`div`w) :: Int->Int->Int->Int->Int) [3,5,8,2]
Related
plusOne :: [[(Int, Int, Int)]] -> [[(Int, Int, Int)]]
Given a list of lists of 3-tuples.
If I want to iterate through the list and +1 to the Int values, how should I approach this? I'm not sure if this is a scenario where Maps should be used or not.
Can someone point me into the right direction?
Split the functions. The lists are easy; one map each. But tuples don't traverse the way they do in e.g. Python, so they require unpacking to access the elements; this is possible with generic programming but far easier with pattern matching. Tuples can hold fields of varying types, so something like map couldn't access all of them. We can make our own map-analogue for triples specifically:
map3t :: (x -> y) -> (x, x, x) -> (y, y, y)
map3t f (a, b, c) = (f a, f b, f c)
Now we can inspect each level of our type and handle it separately:
op :: Int -> Int
op = (+1)
t3 :: (Int, Int, Int) -> (Int, Int, Int)
t3 = map3t op
lt3 :: [(Int, Int, Int)] -> [(Int, Int, Int)]
lt3 = map t3
llt3 :: [[(Int, Int, Int)]] -> [[(Int, Int, Int)]]
llt3 = map lt3
This is not recursion, although map may be implemented using recursion (Data.List.map is). Each function calls a different function for the inner level.
Here is an example of a not very generic way of how we can use map to access nested lists,which also can be matched on 3tuples with a lambda function:
fun :: (Num a, Num b, Num c) => [[(a, b, c)]] -> [[(a, b, c)]]
fun xs = map (map(\(x,y,z) -> (x+1,y+1,z+1))) xs
Pros: En easy and understandable oneliner to solve a specific problem
Cons: Not generic for the function applied to the elements, can become fuzzy and out of hand with more complex and bigger input structures.
Mapping with a hard coded function forcing you to make a new map for each operation. So a better way in that case would be to refactor the function itself, ie :
fun2 f xs = map (map(op f)) xs
where
op f' (x,y,z) = (f' x,f' y, f' z)
Making op a function to which you can give an operation for the specific type.
Making the signature for the function more generic on the types of operations: (Notice here that we can no longer be sure of the type of x,y,z, which before were numerics (because of the +1 operation) giving us a more generic version of the function, but also making us more responsible of matching the types correctly, no string operations on integers etc.)
fun2 :: (t -> c) -> [[(t, t, t)]] -> [[(c, c, c)]]
Define a proper functor to wrap your tuples.
data Three a = Three {getThree :: (a, a, a)} deriving (Show, Functor)
If you don't want to use the DeriveFunctor extension, the definition is simple:
instance Functor Three where
fmap f (Three (x, y, z)) = Three (f x, f y, f z)
Then you can simply define plusOne as
>>> plusOne = let f = getThree . fmap (+1) . Three in fmap (fmap f)
where f is a function that wraps a 3-tuple, maps (+1) over each element, and unwraps the result. This gets mapped over your list of lists:
> x = [[(1, 2, 3), (4,5,6)], [(7,8,9)]]
> plusOne x
[[(2,3,4),(5,6,7)],[(8,9,10)]]
You can also use Data.Functor.Compose to eliminate one of the levels of fmap (or, at least hide it behind another set of names to break up the monotony):
> getCompose . fmap (getThree . fmap (+1) . Three) . Compose $ x
[[(2,3,4),(5,6,7)],[(8,9,10)]]
We've applied the same pattern of wrapping/fmaping/unwrapping twice. We can abstract that away with a helper function
-- wrap, map, and unwrap
wmu pre post f = post . fmap f . pre
plusOne = wmu Compose getCompose $ wmu Three getThree $ (+1)
One might notice a similarity between wmu and dimap (specialized to (->)):
wmu pre post = dimap pre post . fmap
Everything is even simpler if you can replace the generic tuple with a custom product type in the first place.
data Triplet a = Triplet a a a
-- Can be derived as well
instance Functor Triplet where
fmap f (Triplet x y z) = Triplet (f x) (f y) (f z)
plusOne :: [[Triplet Int]] -> [[Triplet Int]]
plusOne = fmap (fmap (fmap (+1)))
I was trying to write a QuickCheck test for the identity
f $ y = f y
My initial plan was to write an arbitrary generator that returns functions & Integer, having the signature Gen (Int -> Int, Int)
and in the prop_DollerDoesNothing test that function application with / without the $ gives the same result.
This was my code:
prop_DollarDoesNothing :: Property
prop_DollarDoesNothing =
forAll arbitraryFuncInt (\(f, y) -> (f $ y) == (f y))
arbitraryFuncInt :: Gen (Int -> Int, Int)
arbitraryFuncInt = do
f <- elements [(\x -> x*2), (\x -> x+3), (\x -> x-2)]
y <- arbitrary :: Gen Int
return (f, y)
And it generated the following helpful error message:
* No instance for (Show (Int -> Int))
arising from a use of `forAll'
(maybe you haven't applied a function to enough arguments?)
* In the expression:
forAll arbitraryFuncInt (\ (f, y) -> (f $ y) == (f y))
In an equation for `prop_DollarDoesNothing':
prop_DollarDoesNothing
= forAll arbitraryFuncInt (\ (f, y) -> (f $ y) == (f y))
So, I fixed the error and got the test working by applying the arbitrary function and returning a pair of ints from arbitraryFuncInt
prop_DollarDoesNothing :: Property
prop_DollarDoesNothing =
forAll arbitraryFuncInt (\(x, y) -> x == y)
arbitraryFuncInt :: Gen (Int, Int)
arbitraryFuncInt = do
f <- elements [(\x -> x*2), (\x -> x+3), (\x -> x-2)]
y <- arbitrary :: Gen Int
return (f $ y, f y)
My questions are:
is it simply not possible to return arbitrary functions that aren't fully applied due to not having an instance for Show?
Can I write an instance for Show (Int -> Int) to make # 1 possible?
Can QuickCheck generate arbitrary functions given a type signature, for cases where I'm testing identities that are true for all functions (of a given type). Above, I specify the 3 test functions by hand, I'd like to automate that somehow, ideally something like this f <- arbitrary :: Gen (Int -> Int)
QuickCheck has support to generate, shrink and show functions, using the Fun type. CoArbitrary enables generation of functions. It is then converted to a (possibly infinite) trie-like structure, that can be inspected and shrunk to a finite value (because a test failure only depends on finitely many inputs), which can then be shown as a counterexample.
Concretely, you can write properties as function that take a Fun argument, which is a wrapper around (->) using the mechanism I described. Deconstruct it with the Fn pattern to get a function.
prop_dollarDoesNothing :: Property
prop_dollarDoesNothing = property $ \(Fn (f :: Int -> Int)) x ->
(f $ x) === f x
For more information
The QuickCheck implementation: https://hackage.haskell.org/package/QuickCheck-2.11.3/docs/Test-QuickCheck-Function.html
The paper "Shrinking and showing functions" by Koen Claessen, which appears to be paywalled, but his talk is online: https://www.youtube.com/watch?v=CH8UQJiv9Q4
Arbitrary can generate functions just fine (provided the arguments are instances of CoArbitrary), it's just the showing part that doesn't work. There's not really a good way to show a function.
This is a common problem, and therefore QuickCheck provides the Blind modifier. It basically fakes a Show instances for any type, not actually showing any information about the value. Of course this somewhat diminishes the debugging-usefulness of a failing test case, but there's not much that can done about this.
This works in the ghci
data MyList a = Empty | Cons a (MyList a) deriving (Show, Eq, Read, Ord)
let x = Cons(21, Cons(12, Empty))
However when I type:
Prelude> x
I get this error:
No instance for (Show (MyList (Integer, MyList (Integer, MyList a0) ->
MyList (Integer, MyList a0)) ->
MyList (Integer, MyList (Integer, MyList a0) ->
MyList (Integer, MyList a0)))) arising from a use of `print'
You are using the wrong syntax for function application. The following code does what you want:
let x = Cons 21 (Cons 12 Empty)
The reason for this is that the Cons constructor is a curried function, but you are treating it as an uncurried function.
Curried functions
Consider the following function adding two integers:
add :: Int -> (Int -> Int)
add = \x -> (\y -> x + y)
Here we say add is a function, which takes an argument x of type Int and returns a function,
which takes an argument y of type Int and returns x + y of type Int.
We can apply this function for example as (add 1) 2 evaluating to 3.
Function application is left-associative in Haskell, which means that we don't need the parentheses
in (add 1) 2 and can simply write add 1 2.
The function type constructor -> is right-associative in Haskell, which means that we don't need the parentheses in add :: Int -> (Int -> Int) and can simply write add :: Int -> Int -> Int.
Also we don't have to explicitly define add using lambdas and can use the following notation:
add :: Int -> Int -> Int
add x y = x + y
Encoding multi-parameter functions as single-parameter functions returning single-parameter functions is quite common in Haskell. This approach has the nice property, that we can also partially apply a function. For example the following function takes a single Int and adds 2:
add2 :: Int -> Int
add2 x = add 2 x
But we can also partially apply add and simply write:
add2 :: Int -> Int
add2 = add 2
This is also called point-free notation, where parameters are referred to as points.
Uncurried functions
An alternative encoding of multi-parameter functions can be done using tuple-values, i.e.
add' :: (Int, Int) -> Int
add' (x, y) = x + y
We can invoke this function for example as add' (2, 3), which constructs the pair (2, 3) :: (Int, Int) and passes it as a single argument to the add' function.
Uncurried <-> Curried
In the standard library are two functions to convert functions between the two styles.
curry :: ((a, b) -> c) -> a -> b -> c
curry f x y = f (x, y)
uncurry :: (a -> b -> c) -> (a, b) -> c
uncurry f (x, y) = f x y
For example curry add' gives us add, and uncurry add gives us add'.
Back to explaining ghci's rambling
Note that we could also write the uncurried application as add'(2, 3), which together with partial application and polymorphism explains why let x = Cons(21, Cons(12, Empty)) doesn't directly lead to an error, but ghci subsequently says misterious things about the evaluation of x.
What happens here is that (12, Empty) is pair of type (Int, MyList a) for some type a.
This pair is then used as the first argument in Cons (12, Empty), so we get a partially applied function which takes
a MyList (Int, MyList a) and appends (12, Empty) as an element to this list.
The same happens for Cons(21, Cons(12, Empty)) where we partially apply a pair of 21 and the before mentioned partial function. In the end we tell ghci to print a function, which it cannot display and hence complains about a missing Show instance for the corresponding function type.
I'm trying to generate a truth table for a given boolean expression. I could do this with creating a new Datatype BoolExpr, but I want to do it with an anonymous function. It's supposed to work like this:
> tTable (\x y -> not (x || y))
output:
F F | T
F T | F
T F | F
T T | F
My approach:
tbl p = [(uncurry p) tuple | tuple <- allval]
where allval=[(x,y) | x <- [False,True], y <- [False,True]]
This works, but only for 2 Arguments. I want to do it for any number of Arguments. So I figured I would make a function that takes the Arguments from a List:
argsFromList f [] = f
argsFromList f (x:xs) = argsFromList (f x) xs
This does not work:
Occurs check: cannot construct the infinite type: t = t1 -> t
Expected type: t -> [t1] -> t1 -> t
Inferred type: (t1 -> t) -> [t1] -> t1 -> t
In the expression: argsFromList (f x) xs
I don't understand what the problem is here.
I would be very grateful if anyone could point me into the right direction or post a link that does.
If you want to build a truth table for boolean functions with an arbitrary number of arguments, you're creating a function that must work for multiple types, so you'll have to use type classes:
{-# LANGUAGE FlexibleInstances #-}
class TruthTable a where
truthTable :: a -> [([Bool], Bool)]
instance TruthTable Bool where
truthTable b = [([], b)]
instance TruthTable a => TruthTable (Bool -> a) where
truthTable f = [ (True : inps, out) | (inps, out) <- truthTable (f True)] ++
[ (False : inps, out) | (inps, out) <- truthTable (f False)]
For example:
*Main> mapM_ print $ truthTable (&&)
([True,True],True)
([True,False],False)
([False,True],False)
([False,False],False)
The problem here is that you're trying to call a function recursively with a different type for the recursive step. Consider the definition:
argsFromList f [] = f
argsFromList f (x:xs) = argsFromList (f x) xs
Let's try to infer the type ourselves. We can immediately see that the first argument f should be a function of at least one argument, the second argument (x:xs) is a list, and the list elements should be the same type as the first argument of f. In the first case the argument f is returned, so the final return type must be the same as the first argument. So we start with this:
argsFromList :: (a -> ?) -> [a] -> (a -> ?)
To find the unknown type ?, we can look at the second case, which consists of a recursive call. The argument xs is the same list type, and the argument (f x) has type ?. Since it's being used as the first argument in the recursive call, which has type (a -> ?), we can now conclude that ? is the same type as (a -> ?) which is therefore the same type as (a -> (a -> ?)) which is therefore the same type as (a -> (a -> (a -> ?))) which is... oops.
That would be the "infinite type", of course.
If you want to do this with functions that use a variable number of arguments of a single type, you'll probably want to use functions that take a list of values rather than individual arguments. Otherwise, you'll have to either write each version individually or use some arcane tricks involving advanced language features, neither of which is appealing in a simple case like this.
What you're asking for is not at all trivial. Haskell doesn't make it easy to deal with functions that apply functions with variable numbers of arguments. For example, the zip functions from Data.List come in separate variants for different numbers of arguments (zip, zip3, zip4, ...). Likewise, in Control.Monad there's liftM, liftM2, liftM3, ...
Basically, the most general type you can assign to a function with an unknown number of arguments is a -> b; a one-place truth function is Bool -> Bool (a = Bool, b = Bool), a two-place truth function is Bool -> (Bool -> Bool) (a = Bool, b = Bool -> Bool), three-place is Bool -> (Bool -> (Bool -> Bool)) (a = Bool, b = Bool -> (Bool -> Bool)), and so on. But there is no easy way you can look at the function you've been passed in to know what's the type on the right of the initial arrow.
One type of solution that can be made to work involves using type classes to define separate instances of the truth-table maker function for each argument function type. Sjoerd Visscher's answer in this thread is doing that for all function sizes by using a recursive instance definition (notice the recursive TruthTable a => TruthTable (Bool -> a) declaration). There may be other solutions that could be constructed using the Applicative type class.
I've seen the other post about this, but is there a clean way of doing this in Haskell?
As a 2nd part, can it also be done without making the function monadic?
The package data-memocombinators on hackage provides lots of reusable memoization routines. The basic idea is:
type Memo a = forall r. (a -> r) -> (a -> r)
I.e. it can memoize any function from a. The module then provides some primitives (like unit :: Memo () and integral :: Memo Int), and combinators for building more complex memo tables (like pair :: Memo a -> Memo b -> Memo (a,b) and list :: Memo a -> Memo [a]).
You can modify JonathanĀ“s solution with unsafePerformIO to create a "pure" memoizing version of your function.
import qualified Data.Map as Map
import Data.IORef
import System.IO.Unsafe
memoize :: Ord a => (a -> b) -> (a -> b)
memoize f = unsafePerformIO $ do
r <- newIORef Map.empty
return $ \ x -> unsafePerformIO $ do
m <- readIORef r
case Map.lookup x m of
Just y -> return y
Nothing -> do
let y = f x
writeIORef r (Map.insert x y m)
return y
This will work with recursive functions:
fib :: Int -> Integer
fib 0 = 1
fib 1 = 1
fib n = fib_memo (n-1) + fib_memo (n-2)
fib_memo :: Int -> Integer
fib_memo = memoize fib
Altough this example is a function with one integer parameter, the type of memoize tells us that it can be used with any function that takes a comparable type. If you have a function with more than one parameter just group them in a tuple before applying memoize. F.i.:
f :: String -> [Int] -> Float
f ...
f_memo = curry (memoize (uncurry f))
This largely follows http://www.haskell.org/haskellwiki/Memoization.
You want a function of type (a -> b). If it doesn't call itself, then
you can just write a simple wrapper that caches the return values. The
best way to store this mapping depends on what properties of a you can
exploit. Ordering is pretty much a minimum. With integers
you can construct an infinite lazy list or tree holding the values.
type Cacher a b = (a -> b) -> a -> b
positive_list_cacher :: Cacher Int b
positive_list_cacher f n = (map f [0..]) !! n
or
integer_list_cacher :: Cacher Int b
integer_list_cacher f n = (map f (interleave [0..] [-1, -2, ..]) !!
index n where
index n | n < 0 = 2*abs(n) - 1
index n | n >= 0 = 2 * n
So, suppose it is recursive. Then you need it to call not itself, but
the memoized version, so you pass that in instead:
f_with_memo :: (a -> b) -> a -> b
f_with_memo memoed base = base_answer
f_with_memo memoed arg = calc (memoed (simpler arg))
The memoized version is, of course, what we're trying to define.
But we can start by creating a function that caches its inputs:
We could construct one level by passing in a function that creates a
structure that caches values. Except we need to create the version of f
that already has the cached function passed in.
Thanks to laziness, this is no problem:
memoize cacher f = cached where
cached = cacher (f cached)
then all we need is to use it:
exposed_f = memoize cacher_for_f f
The article gives hints as to how to use a type class selecting on the
input to the function to do the above, rather than choosing an explicit
caching function. This can be really nice -- rather than explicitly
constructing a cache for each combination of input types, we can implicitly
combine caches for types a and b into a cache for a function taking a and b.
One final caveat: using this lazy technique means the cache never shrinks,
it only grows. If you instead use the IO monad, you can manage this, but
doing it wisely depends on usage patterns.
Doing a direct translation from the more imperative languages, I came up with this.
memoize :: Ord a => (a -> IO b) -> IO (a -> IO b)
memoize f =
do r <- newIORef Map.empty
return $ \x -> do m <- readIORef r
case Map.lookup x m of
Just y -> return y
Nothing -> do y <- f x
writeIORef r (Map.insert x y m)
return y
But this is somehow unsatisfactory. Also, Data.Map constrains the parameter to be an instance of Ord.
If your arguments are going to be natural numbers, you can do simply:
memo f = let values = map f [0..]
in \n -> values !! n
However, that doesn't really help you with the stack overflowing, and it doesn't work with recursive calls. You can see some fancier solutions at http://www.haskell.org/haskellwiki/Memoization.