I have this code:
trimorficos :: [Integer]
trimorficos = filter (trim) [0..]
trim :: Integer -> Bool
trim x = (show x) `isSuffixOf` (show (x^3))
where a = show x
b = show (x^3)
densityTrimorficos :: Integer -> Double
densityTrimorficos n = fromInteger (n - (genericLength (filter (<=10) trimorficos))) / fromInteger n
Why the last function densityTrimorficos doesn't work?
trimorficos is an infinite list.
filter (<=10) trimorficos will never produce the end-of-list [] at the very end. To do so, it should verify that, from a certain point onward, trimorficos contains only numbers >10, but that would require infinite time.
Basically, filter will returns something like a:b:c:nonTerminating instead of a:b:c:[] = [a,b,c].
Consequently, genericLength fails to terminate, since it tries to evaluate nonTerminating into either d:... or [] but that requires infinite time.
As pointed out above in the comments, you probably want takeWhile (<=10) trimorficos instead, which will produce [] as soon as the first >10 number is encountered. Note that this will not check the rest of the list, unlike filter.
Related
I'm learning Haskell and there's a lot of type-checking that seems completely nonsensical to me. I have written a simple function to count the number of occurrences of a given element in a given list, as such:
-- Count the number of occurrences of an element in a list.
countOcc :: (Eq a) => [a] -> a -> Int
countOcc xs x = length $ filter (== x) xs
Now, using this explicitly with calls such as:
countOcc "str" 's'
This executes fine, and returns correctly. However, this causes an error:
countOcc "str" "str"!!0
I haven't the foggiest why this should cause an error. "str"!!0 gives 's', a Char, which is exactly the same type passed in the second parameter of the first call.
I'm sure there are some nuances to Haskell's type system that I'm overlooking, or haven't broached yet. Ideally, I'd like to know why this is erroneous and furthermore, I'd like to know, according to Haskell's ideology, why it should be erroneous.
The following works fine:
countOcc :: (Eq a) => [a] -> a -> Int
countOcc xs x = length $ filter (== x) xs
main = print $ countOcc "str" ("str"!!0) -- 1
As far as I know, function applictaion has the highest precedence; although !! has precedence level of 9, it is still lower than function application.
I'm writing a function to determine whether a number is a palindrome.
What I would like to do in the first case is to destructure the string into the first character, all the characters in the middle, and the last character. What I do is check if the first character is equal to the last, and then if so, proceed to check the middle characters.
What I have is below, but it generates type errors upon compilation.
numberIsPalindrome :: Int -> Bool
numberIsPalindrome n =
case nString of
(x:xs:y) -> (x == y) && numberIsPalindrome xs
(x:y) -> x == y
x -> True
where nString = show n
Using the String representation is cheating...
Not really, but this is more fun:
import Data.List
palindrome n = list == reverse list where
list = unfoldr f n
f 0 = Nothing
f k = Just (k `mod` 10, k `div` 10)
What it does is creating a list of digits of the number (unfoldr is really useful for such tasks), and then comparing whether the list stays the same when reversed.
What you try has several problems, e.g. you miss a conversion from the number to a String (which is just a list of Char in Haskell), and lists work completely different from what you try: Think of them more as stacks, where you usually operate only on one end.
That said, there is an init and a last function for lists, which allow to work your way from the "outer" elements of the list to the inner ones. A naive (and inefficient) implementation could look like this:
palindrome n = f (show n) where
f [] = True
f [_] = True
f (x : xs) = (x == last xs) && (f (init xs))
But this is only for demonstration purposes, don't use such code in real live...
The definition you probably want is
numberIsPalindrome :: Int -> Bool
numberIsPalindrome num = let str = show num
in (str == reverse str)
The (:) operator is known as cons, it prepends items to lists:
1:2:[] results in [1,2]
You are getting a type error because you are trying to compare the first argument, a Char, with the last one, a [a].
If you really would like to compare the first with the last you would use head and last.
But you are better using the solution that taktoa proposed:
numberIsPalindrome :: Int -> Bool
numberIsPalindrome num =
numberString == reverse numberString
where numberString = show num
I want to have a function that reads arbitrary int's until the number '0' is inserted, and then presents the numbers inserted in an ordered list.
For that i wrote this function:
import Data.List
readIntegers :: IO()
readIntegers = do
putStrLn "insert a number: "
num<-getLine
let list = ordList ((read num :: Int):list)
if (read num == 0)
then print list
else readIntegers
where ordList ::[Int]->[Int]
ordList [] = []
ordList xs = sort xs
This compiles just fine, but when i insert the number '0', it gives me this error:
*** Exception: <<loop>>
What am i doing wrong ?
As #phg points out, you are essentially constructing an infinite list, and actually evaluating it causes the loop error. A simple implementation to resolve this issue is to define a helper function which takes an additional parameter - a list to store all the inputs read in from the screen, like so:
readInteger :: IO ()
readInteger = readInteger' []
where
readInteger' x = do
putStrLn "insert a number: "
num<-getLine
if ((read num :: Int) == 0)
then print $ ordList x
else readInteger' $ (read num :: Int):x
where ordList ::[Int]->[Int]
ordList [] = []
ordList xs = sort xs
Please note that the above is essentially just an implementation of #phg's answer, but with some changes to your original logic. Firstly, since 0 is a sentinel value, we shouldn't be appending that to our list. Second, we do not need to sort the list every single time we are adding a value to it. Sorting once at the time of printing/passing to another function is sufficient.
Demo
If you want to read an unspecified number of integers without prompting for user input and cut it off the moment you encounter 0, you would probably do well to use getContents, which will read everything from the standard input as a single string, lazily.
Then, it is a simple matter of parsing it to a list of numbers and doing what you want with it, like so:
readIntegers :: ()
readIntegers = do
a <- getContents
let b = ordList $ takeWhile (/= 0) $ map (\x -> read x :: Int) $ words a
mapM (putStrLn . show) b
where ordList ::[Int]->[Int]
ordList [] = []
ordList xs = sort xs
let list = ordList ((read num :: Int):list)
This is basically a recursive definition of a list of the form [x, x, ...] (like if you wrote an equation saying x = 1 + x). That is perfectly fine by itself, since Haskell is lazy; however, if you try to print list (aka "solve the equation"), it will fail, since it will try to print infinitely many numbers.
You probably have a misconception about the workings of the (:) operator. Haskell functions will never perform an assignment operation and concatenate num onto list by changing it, like in imperative languages. There are only pure functions.
If you want to accumulate all numbers, you should try to come up with a recursive definition of readIntegers, keeping its state (the list) in an additional parameter (there are also more sophisticated ways, hiding the state passing, but more complicated to use for a beginner).
For a more sophisticated solution, note that this is an unfold and you can use unfoldM from Control.Monad.Loops to implement it:
import Control.Monad.Loops (unfoldM)
readInts :: IO [Int]
readInts = unfoldM $ fmap (check . read) getLine
where check x = if x == 0 then Nothing else Just x
This has the nice property that it returns the list in the order in which it was read.
The full practice exam question is:
Using anonymous functions and mapping functions, define Haskell
functions which return the longest String in a list of Strings, e.g.
for [“qw”, “asd”,”fghj”, “kl”] the function should return “fghj”.
I tried doing this and keep failing and moving onto others, but I would really like to know how to tackle this. I have to use mapping functions and anonymous functions it seems, but I don't know how to write code to make each element check with each to find the highest one.
I know using a mapping function like "foldr" can make you perform repeating operations to each element and return one result, which is what we want to do with this question (check each String in the list of Strings for the longest, then return one string).
But with foldr I don't know how to use it to make checks between elments to see which is "longest"... Any help will be gladly appreciated.
So far I've just been testing if I can even use foldr to test the length of each element but it doesn't even work:
longstr :: [String] -> String
longstr lis = foldr (\n -> length n > 3) 0 lis
I'm quite new to haskell as this is a 3 month course and it's only been 1 month and we have a small exam coming up
I'd say they're looking for a simple solution:
longstr xs = foldr (\x acc -> if length x > length acc then x else acc) "" xs
foldr is like a loop that iterates on every element of the list xs. It receives 2 arguments: x is the element and acc (for accumulator) in this case is the longest string so far.
In the condition if the longest string so far is longer than the element we keep it, otherwise we change it.
Another idea:
Convert to a list of tuples: (length, string)
Take the maximum of that list (which is some pair).
Return the string of the pair returned by (2).
Haskell will compare pairs (a,b) lexicographically, so the pair returned by (2) will come from the string with largest length.
Now you just have to write a maximum function:
maximum :: Ord a => [a] -> a
and this can be written using foldr (or just plain recursion.)
To write the maximum function using recursion, fill in the blanks:
maximum [a] = ??? -- maximum of a single element
maximum (a:as) = ??? -- maximum of a value a and a list as (hint: use recursion)
The base case for maximum begins with a single element list since maximum [] doesn't make sense here.
You can map the list to a list of tuples, consisting of (length, string). Sort by length (largest first) and return the string of the first element.
https://stackoverflow.com/a/9157940/127059 has an answer as well.
Here's an example of building what you want from the bottom up.
maxBy :: Ord b => (a -> b) -> a -> a -> a
maxBy f x y = case compare (f x) (f y) of
LT -> y
_ -> x
maximumBy :: Ord b => (a -> b) -> [a] -> Maybe a
maximumBy _ [] = Nothing
maximumBy f l = Just . fst $ foldr1 (maxBy snd) pairs
where
pairs = map (\e -> (e, f e)) l
testData :: [String]
testData = ["qw", "asd", "fghj", "kl"]
test :: Maybe String
test = maximumBy length testData
main :: IO ()
main = print test
I'm playing with Haskell for first time.
I've created function that returns first precise enough result. It works as expected, but I'm using generator for this. How can I replace generator in this task?
integrateWithPrecision precision =
(take 1 $ preciseIntegrals precision) !! 0
preciseIntegrals :: Double -> [Double]
preciseIntegrals precision =
[
integrate (2 ^ power) pi | power <- [0..],
enoughPowerForPrecision power precision
]
You can use the beautiful until function. Here it is:
-- | #'until' p f# yields the result of applying #f# until #p# holds.
until :: (a -> Bool) -> (a -> a) -> a -> a
until p f x | p x = x
| otherwise = until p f (f x)
So, you can write your function like this:
integrateWithPrecision precision = integrate (2 ^ pow) pi
where
pow = until done succ 0
done pow = enoughPowerForPrecision pow precision
In your case, you do all the iteration and then compute a result just once. But until is useful even when you need to compute a result at each step - just use an (iter, result) tuple and then just extract the result at the end with snd.
It seems like you want to check higher and higher powers until you get one that satisfies a requirement. This is what you could do: First you define a function to get enough power, and then you integrate using that.
find gets the first element of a list that satisfies a condition – like being enough of a power! Then we need a fromJust to get the actual value from that. Please note that almost always, fromJust is a terrible idea to have in your code. However, in this case the list is infinite, so we will have troubles with infinite loops long before fromJust is able to crash the program.
enoughPower :: Double -> Int
enoughPower precision =
fromJust $ find (flip enoughPowerForPrecision precision) [0..]
preciseIntegrals :: Double -> Double
preciseIntegrals precision = integrate (2^(enoughPower precision)) pi
The function
\xs -> take 1 xs !! 0
is called head
head [] = error "Cannot take head of empty list"
head (x:xs) = x
Its use is somewhat unsafe, as shown it can throw an error if you pass it an empty list, but in this case since you can be certain your list is non-empty it's fine.
Also, we tend not to call these "generators" in Haskell as they're not a special form but are instead a simple consequence of lazy evaluation. In this case, preciseIntegrals is called a "list comprehension" and [0..] is nothing more than a lazily generated list.