Haskell if statement for checking errors

I wrote a function for the Haar wavelet transform, given that the input is a list with cardinality 2. I tried to check the error by making sure that the list is 2 before transforming the transform. I compare the log base 2 of the list length to see if it works out evenly (nothing to the right of the decimal point). I think something is happening with the ifkell statement that I am not used to in other languages. It works fine if I don't check for errors and just call haar with the correct argument.

haar :: (Fractional a) => [a] -> [a]
haar xs = if logBase 2 (fromIntegral (length xs)) /= truncate (logBase 2 (fromIntegral (length xs)))
             then error "The List must be a power of 2"
             else haarHelper xs (logBase 2 (fromIntegral (length xs)))

haarHelper xs 1 = haarAvgs xs ++ haarDiffs xs
haarHelper xs level = haarHelper (haarAvgs xs ++ haarDiffs xs) (level - 1)

haarAvgs [] = []
haarAvgs (x:y:xs) = ((x + y) / 2.0) : haarAvgs xs 

haarDiffs [] = []
haarDiffs (x:y:xs) = ((x - y) / 2.0) : haarDiffs xs

The following error message appears:

functions.hs:52:13:
    Ambiguous type variable `t' in the constraints:
      `Floating t'
        arising from a use of `logBase' at functions.hs:52:13-48
      `Integral t'
        arising from a use of `truncate' at functions.hs:52:53-99
    Probable fix: add a type signature that fixes these type variable(s)
Failed, modules loaded: none.
+3
source share
5 answers

, , :

import Data.Bits

powerOfTwo' n = n .&. (n-1) == 0

(: , n , , , length.)

:

, 2 1 ( ), , :

2^n      =  100000...
2^n - 1  =  011111...

, .

-- 1 , .

(: , , ).

+4
haar :: (Fractional a) => [a] -> [a]
haar xs | r /= (truncate r) = error "The List must be a power of 2"
        | otherwise = haarHelper xs (logBase 2 (fromIntegral (length xs)))
            where r = logBase 2 (fromIntegral (length xs))

, , - . , haskell . .

, . , truncate int, float.

haar :: (Fractional a) => [a] -> [a]
haar xs | r /= w = error "The List must be a power of 2"
        | otherwise = haarHelper xs (logBase 2 (fromIntegral (length xs)))
            where 
                r = logBase 2 (fromIntegral (length xs))
                w = intToFloat (truncate r) 

haarHelper xs 1 = haarAvgs xs ++ haarDiffs xs
haarHelper xs level = haarHelper (haarAvgs xs ++ haarDiffs xs) (level - 1)

haarAvgs [] = []
haarAvgs (x:y:xs) = ((x + y) / 2.0) : haarAvgs xs 

haarDiffs [] = []
haarDiffs (x:y:xs) = ((x - y) / 2.0) : haarDiffs xs

intToFloat :: Int -> Float
intToFloat n = fromInteger (toInteger n)
+2

:

haar :: (Fractional a) => [a] -> [a]
haar xs | r /= (fromIntegral $ truncate r) = error "The List must be a power of 2"
        | otherwise = haarHelper xs r
            where r = logBase 2 (fromIntegral (length xs))
  • fromIntegral
  • r haarHelper xs r
+1

haar, , :

haar :: (Fractional a) => [a] -> [a]
haar xs = maybe (error "The List must be a power of 2")
                (haarHelper xs)
                (intLogBase 2 $ length xs)

intLogBase :: (Integral a) => a -> a -> Maybe Int
intLogBase b n = intLogBase' b 1 n
  where
    intLogBase' b p 1 = Just p
    intLogBase' b p n
      | r /= 0    = Nothing
      | otherwise = intLogBase' b (p + 1) q 
      where (q, r) = quotRem n b

intBaseLog - baseLog, Nothing, . , Just. logBase truncate : .

maybe . , Nothing, ( ). Just, Just .

0

if. , , "logBase (...)" "" (logBase (...)) ". Floating, Integral. ( ), , .

, , , , . :

powersOfTwo :: [Integer]
powersOfTwo = iterate (*2) 1
isPowerOfTwo x = xInt == head (dropWhile (<xInt) powersOfTwo)
    where xInt = toInteger x

, , , , , "logBase 2". , , . , : truncate (logBase 2 512) == truncate (logBase 2 550) (Edit: , , , , , , , , , logBase 2 (...) - , , ).

0
source

Source: https://habr.com/ru/post/1766883/


All Articles