简体   繁体   中英

Haskell, Length of list returning the value 1

I'm working with some code and there seems to be an issue which I can't figure out.

So I've got a method which decrements an input Int by 1 until it hits 5. (I know if i enter less than 1 it would cause an error but i will fix that later)

I have a second function which calls a takes a List as a parameter which calls this function and returns the list of numbers, I want to call length on this list and populate a separate list (I'm not the best at explaining, i'll show with code examples below)

sub 5 = return [1]
sub x =
    do 
        xs <- sub (x - 1)
        return (x:xs)       


f xs = [ length (sub x) | x<-xs ]

If I call sub 10 on it's own it gives the output [10,9,8,7,6,1], however if I call length on this, it gives the output [1].

In my head i thought the output would be 6, as it has 6 elements in.

Does anyone have any idea why this is happening and/or a way to fix it?

Thanks in advance.

sub doesn't return [10,9,8,6,1] but [[10,9,8,6,1]] (a list of list) therefore the length is 1. You don't need the return. You are in a list monad, return wraps it's value into a list, this why you end up with nested list. Your code should be

sub 5 = [1] -- or return 1
sub x = do
       let xs = sub (x -1)
       (x:xs)

The problem is that this sub function is written like you were in an imperative language and that return doesn't mean the same thing in Haskell : it means "wrap this thing in a Monad (which Monad depends on the context)". Here since you use length on the result of sub the list [] monad is used and the result is [ [10, 9, 8, 7, 6, 5] ] a list of one element which happen to be a list of 6 elements. mb14 correctly identified that but then corrected only the first case of your function, the second case is also monadic but shouldn't be...

sub 5 = [1]
sub x = x : sub (x - 1)

is the simple code you should be using, you don't need any monad here...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM