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?
source to share
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?
source to share
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]
source to share
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]
source to share