How to get all subsets of a number in haskell

I would like to get all subsets of a number from a specific side.

In the case of number 1234 under the numbers on the left side:

1, 12, 123, 1234

      

I have implemented it with:

tail . inits $ show 1234

      

This way I get all the subsets in [[Char]] format.

["1","12","123","1234"]

      

I tried to convert them to Integer with the following line.

map read . tail . inits $ show 1234

      

But I am getting the following error

[*** Exception: Prelude.read: no parse

      

What am I doing wrong?

+3


source to share


4 answers


because the interpreter doesn't know what type you want to return

this will work:

λ> map read . tail . inits $ show 1234 :: [Int]
[1,12,123,1234]

      

of course you can just add the type signature (most likely in your code file):

subnums :: Int -> [Int]
subnums = map read . tail . inits . show

      




in ghci:

λ> subnums 1234
[1,12,123,1234]

      




and a nice exercise can be done without show

/ read

:

subnumbers :: Int -> [Int]
subnumbers 0 = []
subnumbers n =
  n : subnumbers (n `div` 10)

      

Can you solve the order problem here?

+3


source


A good approach is to use unfolding . Although fold (variously known as reduction, accumulation, or aggregation in other languages) can process a list of numbers (or values ​​of other types) to calculate a single result value, an unwrapping starts with one value and expands it into a list of values ​​according to a given function. Consider the type of reversal function:

Data.List.unfoldr :: (b -> Maybe (a, b)) -> b -> [a]

      

We can see what unfoldr

takes the function (b -> Maybe (a, b)

and the initial b

. The result is [a]

. If the function is evaluated before Just (a, b)

, it will be added to the result a

and the sweep will be repeated with a new one b

. If the function is relevant Nothing

, the sweep is complete.

Unfolding function:



f :: Integral b => b -> Maybe (b, b)
f x = if x > 0 
  then Just (x, x `div` 10)  -- append x to result; continue with x/10
  else Nothing               -- x = 0; we're done

      

Now we can solve your problem without any of these show

and read

hackers:

λ> let f = (\x -> if x > 0 then Just (x, x `div` 10) else Nothing)
λ> reverse $ unfoldr f 1234
[1,12,123,1234]

      

+3


source


As Carsten suggests, you need to specify which type you want. This is because it read

is polymorphic in its result type. Until the compiler knows what type you want, it doesn't know which parser to use! Bright type annotation is usually the way to go, but sometimes you might consider a function

asTypeOf :: a -> a -> a
asTypeOf x _ = x

      


how to use it here

I see two obvious uses asTypeOf

here:

λ> asTypeOf (map read . tail . inits $ show 1234) ([0] :: [Int])
[1,12,123,1234]

      

and

λ> map (asTypeOf read length) . tail . inits $ show 1234
[1,12,123,1234]

      

the first one seems a little better and the second one might be a little tricky for beginners, but it works;)

Why? Since it length

has a type [a] -> Int

and therefore the type of the result will be bound to Int

:

λ> :t (`asTypeOf` length)
(`asTypeOf` length) :: ([a] -> Int) -> [a] -> Int

      

what do we need for read

Note that it doesn't matter what it does length

- just this type - any other function with a compatible signature is important (although I can only with now length

)

For example:

wantInt :: [a] -> Int
wantInt = undefined

λ> map (asTypeOf read wantInt) . tail . inits $ show 1234
[1,12,123,1234]

      

+2


source


Worklist understanding solution:

subNums :: Int -> [Int]
subNums num = [read x | let str = show num, let size = length str, n <- [1 .. size], let x = take n str]

λ> subNums 1234
[1,12,123,1234]

      

+1


source







All Articles