Haskell 两项职能的工作

Haskell 两项职能的工作,haskell,Haskell,我正在把数字从八进制转换成十进制。我得到的数字是[Char],因此我决定先将其转换为[Int],然后将每个数字乘以相应的8的幂。最后,我计划使用求和得到我的十进制数。如何使两个函数逐个工作 import Data.Char charToDigit :: [Char] -> [Int] -- "123" -> [1,2,3] charToDigit [] = [] charToDigit (x:xs) = digitToInt x : charToDigit xs digitToD

我正在把数字从八进制转换成十进制。我得到的数字是
[Char]
,因此我决定先将其转换为
[Int]
,然后将每个数字乘以相应的8的幂。最后,我计划使用
求和
得到我的十进制数。如何使两个函数逐个工作

import Data.Char

charToDigit :: [Char] -> [Int] -- "123" -> [1,2,3]
charToDigit [] = []
charToDigit (x:xs) = digitToInt x : charToDigit xs

digitToDec :: [Int] -> [Int] -- [1,2,3] -> [64,16,3]
digitToDec [] = []
digitToDec (x:xs) = x * 8^(length xs) : digitToDec xs

octToDec :: [Char] -> Int
octToDec (x:xs) = charToDigit (x:xs) >>= digitToDec (x:xs) >>= sum (x:xs) -- "123" -> [1,2,3] -> [64,16,3] -> 64+16+3 = 83

使用普通函数组合运算符
(.)
组合函数:

(.) :: (b -> c) -> (a -> b) -> a -> c
>=
是一元绑定运算符:

(>>=) :: forall a b. m a -> (a -> m b) -> m b
您的问题的解决方案很简单:

octToDec = sum . digitToDec . charToDigit

使用普通函数组合运算符
(.)
组合函数:

(.) :: (b -> c) -> (a -> b) -> a -> c
>=
是一元绑定运算符:

(>>=) :: forall a b. m a -> (a -> m b) -> m b
您的问题的解决方案很简单:

octToDec = sum . digitToDec . charToDigit

只是为了练习,实现此功能的另一种方法可以是:

digits :: String -> [Int]
digits n | n == "" || n == "0" = []
         | otherwise           = ((++) <$> digits . show . (`div` 10) <*> return . (`rem` 10)) . read $ n

oct2dec :: String -> Int
oct2dec s = snd . foldr (\d r -> (1 + (fst r), snd r  + d * 8^(fst r))) (0,0) $ digits s

*Main> oct2dec "123"
83
digits::String->[Int]
数字n | n==“”| n==“0”=[]
|否则=(++)位。显示。(`div`10)返回。`rem`10)。读$n
oct2dec::String->Int
oct2dec s=snd。foldr(\dr->(1+(fstr),sndr+d*8^(fstr))(0,0)$s
*Main>oct2dec“123”
83

仅出于练习目的,实现此功能的另一种方法可能是:

digits :: String -> [Int]
digits n | n == "" || n == "0" = []
         | otherwise           = ((++) <$> digits . show . (`div` 10) <*> return . (`rem` 10)) . read $ n

oct2dec :: String -> Int
oct2dec s = snd . foldr (\d r -> (1 + (fst r), snd r  + d * 8^(fst r))) (0,0) $ digits s

*Main> oct2dec "123"
83
digits::String->[Int]
数字n | n==“”| n==“0”=[]
|否则=(++)位。显示。(`div`10)返回。`rem`10)。读$n
oct2dec::String->Int
oct2dec s=snd。foldr(\dr->(1+(fstr),sndr+d*8^(fstr))(0,0)$s
*Main>oct2dec“123”
83

使用
()
运算符:
octToDec=sum。数字化。charToDigit
。但你的方法相当低效。只是一个很小的观察:我发现名称
octToDec
有点误导。它确实需要八进制数字作为输入,所以
octTo…
部分很好。它不产生十进制数字或任何基数的数字:它产生
Int
值本身,它与
…Dec
没有任何关系。也许
octToInt
parseOct
octToValue
更合适。或者,如果您要用更明显的方式编写它-
octToDec x=sum(digitodec(charToDigit x))
使用
(。
运算符:
octToDec=sum。数字化。charToDigit
。但你的方法相当低效。只是一个很小的观察:我发现名称
octToDec
有点误导。它确实需要八进制数字作为输入,所以
octTo…
部分很好。它不产生十进制数字或任何基数的数字:它产生
Int
值本身,它与
…Dec
没有任何关系。也许
octToInt
parseOct
octToValue
更合适。或者,如果您要用更明显的方式来编写它-
octToDec x=sum(digitodec(charToDigit x))