Преобразование строки, представляющей двоичное число, в базу 10 строк haskell

У меня есть строка "1001", и мне нужна строка "9".

В числовой библиотеке есть (довольно неуклюжая) showIntAtBase, но мне не удалось найти обратное.

Ответ 1

Вот более или менее то, что вы искали от Prelude. Из Numeric:

(NB: readInt является "двойным" из showIntAtBase, а readDec является "двойным" из showInt. Непоследовательное именование - это исторический случай.)

import Data.Char  (digitToInt)
import Data.Maybe (listToMaybe)
import Numeric    (readInt)

readBin :: Integral a => String -> Maybe a
readBin = fmap fst . listToMaybe . readInt 2 (`elem` "01") digitToInt
-- readBin "1001" == Just 9

Ответ 2

Прошло некоторое время с момента публикации, но для будущих читателей я бы использовал следующее:

import Data.Char (digitToInt)
import Data.List (foldl')

toDec :: String -> Int
toDec = foldl' (\acc x -> acc * 2 + digitToInt x) 0

Не нужно замедлять работу, используя ^, reverse, zipWith, length и т.д.

Кроме того, использование строгой фальшивки снижает требования к памяти.

Ответ 3

Из PLEAC:

bin2dec :: String -> Integer
bin2dec = foldr (\c s -> s * 2 + c) 0 . reverse . map c2i
    where c2i c = if c == '0' then 0 else 1

Ответ 5

Поскольку

1001 = 1 * 2^0 + 0 * 2^1 + 0 * 2^2 + 1 * 2^3 = 1 + 0 + 0 + 8 = 9

┌───┬───┬───┬───┐
│1  │0  │0  │1  │
├───┼───┼───┼───┤
│2^3│2^2│2^1│2^0│
└───┴───┴───┴───┘

так очевидно:

fromBinary :: String -> Int
fromBinary str = sum $ zipWith toDec (reverse str) [0 .. length str]
  where toDec a b = digitToInt a * (2 ^ b)

Ответ 6

binario :: Int -> [Int]                      
binario 1 = [1]                  
binario n = binario(div x 2)++(mod n 2:[])

кредиты @laionzera