I'm new to Haskell and struggling with some subtleties of syntax. Why is this fine:
reduceBy a f n
| n < 2 = (a,f)
| (a `mod` n) == 0 =
reduceBy( floor $ fromIntegral a / fromIntegral n) (f++[n]) n
| otherwise = (a, f)
While this has errors: (Couldn't match expected type `(a, [a])' against inferred type `[a] -> a -> (a, [a])' )
reduceBy a f n
| n < 2 = (a,f)
| (a `mod` n) == 0 =
reduceBy( floor(fromIntegral a / fromIntegral n) (f++[n]) n )
| otherwise = (a, f)
?
Your new closing parenthesis comes too late. It should be
... reduceBy (floor(fromIntegral a / fromIntegral n)) ...
The $ binds fairly weakly, but parentheses trump everything.
Related
I wrote a function in Haskell to compute the determinant of a Matrix, it works just fine but is horribly slow so I tried to memoize it just like the Haskell Wiki does with the Fibonacci function.
But somehow my memoized function takes slightly longer than the non-memoized version, even when computing the determinant for the identity matrix, which should benefit very much from memoization.
I also tried using a Map for caching results but found no way to pass the modified Map to the next iteration of the recursive function.
How can I fix this?
-- Non-Memoized version
det :: (Num a, Eq a) => [[a]] -> a
det x
| fst s == 0 = 0
| fst s == 1 = head $ head x
| fst s == 2 = (head (head x) * ((x !! 1) !! 1))
- ((head x !! 1) * head (x !! 1))
| F.allEqual x = 0
| otherwise = sum [((-1) ^ (i + 1)) * head (x !! (i - 1))
* det (sub x i 1)
| i <- [1..(fst s)]]
where
s = shape x
-- Memoized version
mDet :: (Num a, Eq a) => [[a]] -> a
mDet x = sum [((-1) ^ (i + 1)) * head (x !! (i - 1))
* det' (sub x i 1)
| i <- [1..(fst $ shape x)]]
where
det' y
| fst s == 0 = 0
| fst s == 1 = head $ head y
| fst s == 2 = (head (head y) * ((y !! 1) !! 1))
- ((head y !! 1) * head (y !! 1))
| F.allEqual y = 0
| otherwise = mDet y
where
s = shape y
There are much more efficient algorithms to compute the determinant via factorization.
Even with memoization, there are an exponential number of submatrices involved in the naive determinant formula so that's a little pointless.
Just for reference, your function re-written to avoid the !! access becomes
-- Non-Memoized version
det :: (Num a, Eq a) => [[a]] -> a
det [] = 0
det [r] = head r
det [r,q] = case [r,q] of
[[a,b],[c,d]] -> a*d - b*c -- error out on wrong shape
det x | or [ or [a==b | b <- bs] -- quadratic test
| (a:bs) <- tails x ] -- (must be "collinear",
= 0 -- "any", not "all"! -- not "==", anyway)
det x = sum $ [s * head r * det ([reverse a,b] >>= map tail)
| (a,r,b) <- picks3 x
| s <- cycle [1,-1]]
picks3 :: [a] -> [([a], a, [a])]
picks3 xs = unfoldr (\case { (_,[]) -> Nothing ;
(a,x:xs) -> Just ((a,x,xs), (x:a,xs)) })
([],xs)
There's nothing to be memoized here that's immediately apparent.
I tried this
recursion n x = if mod n 2 == 0
then x/n + (recursion (n-1) x)**(-1)
else n/x + (recursion (n-1) x)**(-1)
but there's a problem
Ambiguous type variable ‘a0’ arising from a use of ‘print’
prevents the constraint ‘(Show a0)’ from being solved.
Probable fix: use a type annotation to specify what ‘a0’ should be.
These potential instances exist:
instance Show Ordering -- Defined in ‘GHC.Show’
instance Show Integer -- Defined in ‘GHC.Show’
instance Show a => Show (Maybe a) -- Defined in ‘GHC.Show’
...plus 22 others
...plus 18 instances involving out-of-scope types
(use -fprint-potential-instances to see them all)
• In a stmt of an interactive GHCi command: print it
how to solve that problem and what's wrong with my code?
The mod n 2 == 0 constraints n to be an Integral type, but then you use x/n and since the (/) function has signature (/) :: Fractional a => a -> a -> a, this means that x and n have the same Fractional type. It makes no sense that a number type is both Integral and Fractional.
You can work with fromIntegral to convert n to a Fractional type:
recursion :: (Integral a, Floating b) => a -> b -> b
recursion n x = if mod n 2 == 0
then x/fromIntegral n + (recursion (n-1) x)**(-1)
else fromIntegral n/x + (recursion (n-1) x)**(-1)
Another problem with your function is that there is no stop condition. You need to add an extra clause:
recursion :: (Integral a, Floating b) => a -> b -> b
recursion n x
| n <= 0 = 0
| mod n 2 == 0 = x/fromIntegral n + (recursion (n-1) x)**(-1)
| otherwise = fromIntegral n/x + (recursion (n-1) x)**(-1)
This then produces for example:
Prelude> recursion 10 2
0.3481658094621751
Other answers have already explained the errors here. A nice Haskell way to solve this problem is as follows:
import Data.List (scanl')
getNthApprox n x = approximations !! n where
approximations = scanl' (+) 0 $ fmap term [1..]
term n = if n `mod` 2 == 0
then x / fromIntegral n
else fromIntegral n / x
It turns out that due to the magic of laziness, getNthApprox works out to have the same performance characteristics as tail recursion. This is because elements of scanl' (+) 0 $ fmap term [1..] are constructed only as they are needed in the calculation of approximations !! n.
Probably not an answer but this one would correspond more closely to the caption:
tSumToN :: (Enum a, Fractional a) => Int -> a -> a
tSumToN n = sum . take n . tSeq
tSeq :: (Enum a, Fractional a) => a -> [a]
tSeq x =
interleave odds evens
where
odds = [ o / x | o <- [1,3..]]
evens = [ x / e | e <- [2,4..]]
interleave [] _ = []
interleave (y:ys) zs = y:interleave zs ys
example :: Double
example = tSumToN 4 1.1
btw: this one does obviously not converge mathematically so it seems rather pointless to take partial sums - but hey whatever
The errors you are seeing are because the compiler can't figure out the argument types for the function. Adding type constraints to the function takes care of this:
recursion :: (Integral a, Floating b) => a -> b -> b
recursion n x = if mod n 2 == 0
then x/fromIntegral n + (recursion (n-1) x)**(-1)
else fromIntegral n/x + (recursion (n-1) x)**(-1)
Now the function compiles but will not terminate because there is no check for a terminal condition (n==0). To fix this, add the check.
recursion :: (Integral a, Floating b) => a -> b -> b
recursion n x | n == 0 = 0.0
| mod n 2 == 0 = x/fromIntegral n + (recursion (n-1) x)**(-1)
| otherwise = fromIntegral n/x + (recursion (n-1) x)**(-1)
Now the function will terminate with an answer but the answer does not match the formula stated in the question title. To fix this, remove the **(-1) .
recursion :: (Integral a, Floating b) => a -> b -> b
recursion n x | n == 0 = 0.0
| mod n 2 == 0 = x/fromIntegral n + (recursion (n-1) x)
| otherwise = fromIntegral n/x + (recursion (n-1) x)
Now the function returns the correct values. The following main program verifies that this is the case:
main :: IO ()
main = do
print $ recursion 1 1.0
print $ 1/1.0
print $ recursion 2 1.0
print $ 1/1.0 + 1.0/2
print $ recursion 3 1.0
print $ 1/1.0 + 1.0/2 + 3/1.0
print $ recursion 4 1.0
print $ 1/1.0 + 1.0/2 + 3/1.0 + 1.0/4
The function returns the correct values but is not tail recursive. As a first step in making it tail recursive, reduce it to a single recursive call. To do this note that the terms in the formula come in pairs and group them together along with a n-2 recursion. The function now will only work for even n but that can be patched up later.
recursion :: (Integral a, Floating b) => a -> b -> b
recursion n x | n == 0 = 0.0
| otherwise = fromIntegral (n-1)/x + x/fromIntegral n + (recursion (n-2) x)
The function still is not tail recursive because there is additional processing (additions) done after the recursive call. One way to work around this is to introduce an accumumator argument to hold incomplete values.
recursion :: (Integral a, Floating b) => a -> b -> b -> b
recursion n x acc | n == 0 = acc
| otherwise = recursion (n-2) x (fromIntegral (n-1)/x + x/fromIntegral n + acc)
As a final step a wrapper function can be introduced to handle odd values of n and to hide the accumulator argument. Use an appropriately modified version of the above test code to verify.
no_recursion :: (Integral a, Floating b) => a -> b -> b
no_recursion n x = if mod n 2 == 0
then recursion n x 0.0
else fromIntegral n / x + recursion (n-1) x 0.0
What you apparently meant was
recursion n x = if snd (properFraction (n / 2)) > 0 -- isOdd
then x/n + recursion (n-1) (x**(-1))
else n/x + recursion (n-1) (x**(-1))
but there's two problems here. First of all correctness, since you start from nth term and go back to 0th, but use x as the starting value always, whereas it differs depending on whether n is even or odd. We fix problems like this by moving the actual work into the inner, "worker" function, and fixing the starting value of the iteration.
Second problem is that it is not tail recursive. We fix problems like that by introducing an accumulating parameter to the inner, "worker" function. One tool to fix two problems!
-- T = 1/x + x/2 + 3/x + x/4 + ...
recursion :: RealFrac a => a -> a -> a
recursion n x = if snd (properFraction (n / 2)) > 0 -- n is odd
then goOdd n 0
else goEven n 0
where
goOdd n acc = goEven (n-1) (acc + n/x)
goEven n acc
| n <= 0 = acc
| otherwise = goOdd (n-1) (acc + x/n)
Now it's correct, and tail recursive as you wanted.
I'm new to Haskell and i don't understand why my guard won't accept it. here's my code. The guard should fire in case b is a divider of a.
gCF :: Integer -> Integer -> Integer;
gCF n p
| (p <= 0 || n <= 0) = error "Input should be positive"
| (p > n) = f p n
| otherwise = f n p
where
f :: Integer -> Integer -> Integer;
f a b
| (fromInteger (a `div` b) / 1 == a / b) = b
| otherwise = f a (b - 1)
Here's the error shown.
testscript.hs:168:28: error:
• No instance for (Fractional Integer) arising from a use of ‘/’
• In the first argument of ‘(==)’, namely
‘fromInteger (a `div` b) / 1’
In the expression: (fromInteger (a `div` b) / 1 == a / b)
In a stmt of a pattern guard for
an equation for ‘f’:
(fromInteger (a `div` b) / 1 == a / b)
|
168 | | (fromInteger (a `div` b) / 1 == a / b) = b | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
I think you make it the function more complex that necessary. Converting numbers between the Integer and Floating world can be dangerous, since it introduces rounding problems.
If I understand it correctly, you want to check if a is dividable by b. You can check this by verifying that mod a b == 0, and we are still in the integer worlds. So we can rewrite the program to:
gCF :: Integer -> Integer -> Integer
gCF n p | p <= 0 || n <= 0 = error "Input should be positive"
| p > n = f p n
| otherwise = f n p
where f a b | mod a b == 0 = b
| otherwise = f a (b-1)
Since a does not change in the recursive calls, we can factor that out:
gCF :: Integer -> Integer -> Integer
gCF n p | p <= 0 || n <= 0 = error "Input should be positive"
| otherwise = f (min p n)
where a = max p n
f b | mod a b == 0 = b
| otherwise = f (b-1)
We can also generalize the signature to let it work with any Integral type:
gCF :: Integral i => i -> i -> i
gCF n p | p <= 0 || n <= 0 = error "Input should be positive"
| otherwise = f (min p n)
where a = max p n
f b | mod a b == 0 = b
| otherwise = f (b-1)
i found a solution!
gCF :: Integer -> Integer -> Integer;
gCF n p
| (p <= 0 || n <= 0) = error "Input should be positive"
| (p > n) = floor (f (fromInteger p) (fromInteger n) (fromInteger n))
| otherwise = floor (f (fromInteger n) (fromInteger p) (fromInteger p))
where
f :: Float -> Float -> Float -> Float;
f a b c
| (fromInteger (floor (a / c)) == a / c) && (fromInteger (floor (b / c)) == b / c) = c
| otherwise = f a b (c - 1)
With gcd its fairly easy but i do not understand how to tie in all the functions to make it happen without.
kgv :: Int -> Int -> Int
kgv x y = abs ((x `quot` (gcd x y)) * y)
I got this function to find the prime factors which works (prime_factors) and I am working on making a function that takes the maximum number from one list and checks if its on the other list (comp):
prime_factors :: Int -> [Int]
prime_factors 1 = []
prime_factors n
| factors == [] = [n]
| otherwise = factors ++ prime_factors (n `div` (head factors))
where factors = take 1 $ filter (\x -> (n `mod` x) == 0) [2 .. n-1]
comp :: [Int]->Int
comp (ys)(x:xs)
|maximum prime_factors xs elem prime_factors ys == x
|otherwise tail x
kgv :: Int -> Int -> Int
kgv x y = abs ((x `quot` (comp x y)) * y)
Here's an absurdly simple and obscenely inefficient solution:
lcm m n = head [x | x <- [1..], x `rem` m == 0, x `rem` n == 0]
Of course, this relies on two different notions of "least" coinciding under the circumstances, which they do. A fully naive solution doesn't seem possible.
here is the (very) naive algorithm I was talking about:
kgv :: (Ord a, Num a) => a -> a -> a
kgv x y = find x y
where find i j
| i == j = i
| i < j = find (i+x) j
| i > j = find i (j+y)
it's basically what a school-child would do ;)
caution I ignored negative numbers and 0 - you'll probably have to handle those
perhaps another easy way is
import Data.List(intersect)
lcm m n = head $ intersect (series m n) (series n m)
where series a b = take a $ map (*b) [1..]
I figured it out myself mostly. Thanks for the ideas and pointers.
ggt n m | n > m = maximum [t | t <- [1 .. m], gt n m t]
| otherwise = maximum [t | t <- [1 .. n], gt n m t]
gt n m c = t n c && t m c
t n c | n >= c = (mod n c == 0)
| otherwise = False
kgv :: Int -> Int -> Int
kgv x y |x==0=0|y==0=0 |otherwise = abs ((x `quot` (ggt x y)) * y)
I'm trying to implement in Haskell the Wiener's Algorithm from the book Cryptography: Theory and Practice, Third Edition. Here's what I've written so far:
import Data.List
wiener e n = factors
where euclid = euclidean e n
cs = 1 : head euclid : rest cs euclid
ds = 0 : 1 : rest ds euclid
ns = filter isInt $ drop 2 $ zipWith (\x y -> (x * e - 1) / y) ds cs
qs = map (\x -> quad 1 (x - n - 1) n) ns
factors = find (\(p, q) -> isInt p && 0 < p && p < n
&& isInt q && 0 < q && q < n) qs
rest xs ys = zipWith (+) xs (zipWith (*) (tail ys) (tail xs))
euclidean _ 0 = []
euclidean a b = a `div` b : euclidean b (a `mod` b)
quad a b c
| d > 0 = ((-b + sqrt d) / (2 * a), (-b - sqrt d) / (2 * a))
| otherwise = (0.0, 0.0)
where d = b * b - 4 * a * c
isInt x = x == fromInteger (round x)
Trying wiener 238123333 293719721 gives me:
No instance for (RealFrac a0) arising from a use of `wiener'
The type variable `a0' is ambiguous
Possible fix: add a type signature that fixes these type variable(s)
No instance for (Num a0) arising from the literal `238123333'
The type variable `a0' is ambiguous
Possible fix: add a type signature that fixes these type variable(s
How should I proceed? Is there any general number type such that it can be used everywhere?
I tracked down the error. The return type of euclidean is Integral a => [a] while quad returns an instance of RealFrac. Since you use the value n and e as arguments to both functions, n and e must be instances of both typeclasses.
wiener :: (Floating b, Integral a, RealFrac b) => a -> a -> Maybe (b,b)
wiener e' n' = factors
where euclid = map fromIntegral $ euclidean e' n' -- convert result from `Integral` to `Num`
e = fromIntegral e' -- convert Integral to Num
n = fromIntegral n'
cs = 1 : head euclid : rest cs euclid
ds = 0 : 1 : rest ds euclid
ns = filter isInt $ drop 2 $ zipWith (\x y -> (x * e - 1) / y) ds cs
qs = map (\x -> quad 1 (x - n - 1) n) ns
factors = find (\(p, q) -> isInt p && 0 < p && p < n
&& isInt q && 0 < q && q < n) qs
rest xs ys = zipWith (+) xs (zipWith (*) (tail ys) (tail xs))