Even if you fix the typo you'll still get an error, since length returns an Int where you need an Integer. The following is one way to fix this (I've also rewritten your code to use guards):
import Data.List (genericLength)
dreiNplusEins :: Integer -> [Integer]
dreiNplusEins 1 = [1]
dreiNplusEins n
| n `mod` 2 == 0 = n : dreiNplusEins (n `div` 2)
| otherwise = n : dreiNplusEins (n * 3 + 1)
maxZyklus :: UntereGrenze -> ObereGrenze -> (UntereGrenze, ObereGrenze, MaxZyklaenge)
maxZyklus m n
| m == n = (m, n, genericLength $ dreiNplusEins m)
| otherwise = (m, n, 0)
type UntereGrenze = Integer
type ObereGrenze = Integer
type MaxZyklaenge = Integer
You could also use fromIntegral . length if you don't want the extra import, but I personally think genericLength is a little clearer.
Also, if you're interested, here's an arguably nicer way to write the first function:
dreiNplusEins :: Integer -> [Integer]
dreiNplusEins = (++[1]) . takeWhile (/=1) . iterate f
where
f n | even n = n `div` 2
| otherwise = n * 3 + 1
This just says "iteratively apply f until you hit a 1, and then tack a 1 on the end".
To find the number in a given range that produces the longest chain, you can use the following function:
longestBetween :: (Enum a, Integral b) => (a -> [b]) -> (a, a) -> (a, b)
longestBetween f (m, n)
= maximumBy (comparing snd)
. zip [m..n] $ map (genericLength . f) [m..n]
The first argument is the function that creates the list and the second is the range. The return value is a tuple containing the desired number in the range and the length of its list. Note that we need these additional imports:
import Data.List (genericLength, maximumBy)
import Data.Ord (comparing)
We can test as follows:
*Main> longestBetween dreiNplusEins (100, 1000)
(871,179)
Implementing the maxZyklus function you specify in the comments just takes a couple of minor changes at this point:
maxZyklus m n = (m, n, maximum $ map (genericLength . dreiNplusEins) [m..n])
maxZyklus 11 22 gives the desired (11, 22, 21).