0

i'm newbie and trying to learn haskell, but i'm having a problem in the Data.List chapter of learnyouahaskell as follows:

let xs = [1..6] in sum xs / genericLength xs    -- > it works

Now I try to add the drop function to calculate the average for some elements t want:

let xs = [1..6] in sum xs / genericLength (drop xs) -- > it works
let xs = [1..6] in sum xs / genericLength $ drop xs -- > it doesn't work
let xs = [1..6] in sum xs / genericLength . drop xs -- > also not working

i want to know what is the problem?

1 Answer 1

1

What????

First of all, you should just use length instead of genericLegth.

λ > let xs = [1..6] in sum xs / length (drop xs)

<interactive>:7:42: error:
    • Couldn't match expected type ‘Int’ with actual type ‘[a1]’
    • In the first argument of ‘drop’, namely ‘xs’
      In the first argument of ‘length’, namely ‘(drop xs)’
      In the second argument of ‘(/)’, namely ‘length (drop xs)’

The problem is that drop takes two input arguments, not 1 as you have given it in all three examples (the last of which is just wrong).

λ > :t drop
drop :: Int -> [a] -> [a]

Fixing that problem, you get another:

λ > let xs = [1..6] in sum xs / length (drop 2 xs)

<interactive>:9:20: error:
    • No instance for (Fractional Int) arising from a use of ‘/’
    • In the expression: sum xs / length (drop 2 xs)
      In the expression: let xs = [1 .. 6] in sum xs / length (drop 2 xs)
      In an equation for ‘it’:
          it = let xs = ... in sum xs / length (drop 2 xs)

Now, you have a problem with the / operator not being usable with Int.

The solution is:

let xs = [1..6] in fromIntegral (sum xs) / fromIntegral (length $ drop 2 xs)
5.25

The reason this does not work:

let xs = [1..6] in sum xs / length $ drop 2 xs

is because it gets desugared to:

let xs = [1..6] in (sum xs / length) (drop 2 xs)

which does not make sense.

4
  • Thank you very much, you have explained it very clearly to me, have a good day, hope to get more help from you in the future. Commented Mar 8, 2022 at 5:03
  • one more problem, hope you can explain it to me, for example drop has its type defined as follows: drop :: Int -> [a] -> [a] if I want to redefine my own drop function: drop' :: Num -> [a] -> [a] ----> it doesn't work even though Num includes Int in it. sorry for the stupid question, i'm a newbie and learning it from scratch Commented Mar 8, 2022 at 6:09
  • Num is not a type, its a type class. I suspect what you want is: ``` drop' :: Num b => b -> [a] -> [a] ``` The part to the left of the => is a type constraint which says that b has to be a type that has a Num type class instance. Commented Mar 9, 2022 at 6:39
  • thank you very much, you clarified my problem, i got it. Have a nice day Commented Mar 12, 2022 at 12:48

Not the answer you're looking for? Browse other questions tagged or ask your own question.