Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Haskell中将两个函数相加_Haskell - Fatal编程技术网

在Haskell中将两个函数相加

在Haskell中将两个函数相加,haskell,Haskell,嗨,我是哈斯凯尔的新手,我遇到了一个有趣的问题,但我真的不确定如何着手解决它。我将向大家展示问题的两个部分作为示例 问题是我们要输入一个13到15位之间的数字。 然后从这个数字中删除最后一个数字。例如19283828382133应该输出完全相同的数字,只是没有最后的3,192838213 然后这些数字中的每一个奇数(不是数字)都将加倍。所以你会得到2,9,4,8,6等等 这是到目前为止我的代码。正如您从代码中看到的,我已经能够单独完成这两个部分(工作),但我不确定如何将它们添加到一起。 last

嗨,我是哈斯凯尔的新手,我遇到了一个有趣的问题,但我真的不确定如何着手解决它。我将向大家展示问题的两个部分作为示例

问题是我们要输入一个13到15位之间的数字。 然后从这个数字中删除最后一个数字。例如19283828382133应该输出完全相同的数字,只是没有最后的3,192838213

然后这些数字中的每一个奇数(不是数字)都将加倍。所以你会得到2,9,4,8,6等等

这是到目前为止我的代码。正如您从代码中看到的,我已经能够单独完成这两个部分(工作),但我不确定如何将它们添加到一起。

lastdigit :: Integer -> Integer -- This Function removes the last number
lastdigit x = x`div`10

doubleOdd (x:xs) = (2*x):(doubleEven xs) -- This function doubles every odd digit not number.
doubleOdd [] = []
doubleEven (x:xs) = x:(doubleOdd xs)
doubleEven [] = []

因此,为了进一步解释我试图构建的程序,将首先通过输入13到15位数字的步骤。然后,它将首先删除最后一个数字,然后自动进入下一步,将每个奇数(不是数字)加倍。谢谢

首先,您需要一种将一些大数字分解为数字的方法

digits :: Integral x => x -> [x]
digits 0 = []
digits x = digits (x `div` 10) ++ [x `mod` 10]
这给了你

Prelude> digits 12345
[1,2,3,4,5]
然后,您可以使用
init

Prelude> (init . digits) 12345
[1,2,3,4]
该函数使用助手函数将映射到列表中的奇数元素上

mapOdd _ [] = []
mapOdd f (x:[]) = [f x]
mapOdd f (x:y:rest) = f x : y : mapOdd f rest
给你

Prelude> mapOdd (+10) [1..10]
[11,2,13,4,15,6,17,8,19,10]
还有一个返回到大量数据的函数

undigits = sum . zipWith (*) [10^n | n <- [0..]] . reverse
把它们放在一起

Prelude> undigits . mapOdd (*2) . init . digits $ 12345
2264


特别是在函数式语言中,总是试图通过编写较小问题的解决方案来解决问题:)

首先,您需要一种将一些大数字分解为数字的方法

digits :: Integral x => x -> [x]
digits 0 = []
digits x = digits (x `div` 10) ++ [x `mod` 10]
这给了你

Prelude> digits 12345
[1,2,3,4,5]
然后,您可以使用
init

Prelude> (init . digits) 12345
[1,2,3,4]
该函数使用助手函数将映射到列表中的奇数元素上

mapOdd _ [] = []
mapOdd f (x:[]) = [f x]
mapOdd f (x:y:rest) = f x : y : mapOdd f rest
给你

Prelude> mapOdd (+10) [1..10]
[11,2,13,4,15,6,17,8,19,10]
还有一个返回到大量数据的函数

undigits = sum . zipWith (*) [10^n | n <- [0..]] . reverse
把它们放在一起

Prelude> undigits . mapOdd (*2) . init . digits $ 12345
2264


特别是在函数式语言中,始终尝试通过编写较小问题的解决方案来解决问题:)

缺少的组件是一种将整数分解为数字并从中重新构建的方法。这很简单:

digits:: Int -> [Int]
digits = map (`mod` 10) . takeWhile (/= 0) . iterate (`div` 10)

undigits :: [Int] -> Int
undigits = foldr f 0 where f i r = 10 * r + i
然后,看起来您需要以两种不同的方式对这些数字进行后处理,但前提是它们与谓词匹配。让我们为此构建一个组合器:

when :: (a -> Bool) -> (a -> a) -> a -> a
when p f a = if p a then f a else a
第一种情况是在奇数位置(从左到右)输入两位数。同样是琐碎的,有一点小小的不便,
数字
通过增加十的幂来分解数字。让我们以每个数字的位置作为前缀:

prefix :: [Int] -> [(Int, Int)]
prefix is = let n = length is in zip [n, n-1..1] is
双奇数
现在可以表示为

doubleodd :: [Int] -> [Int]
doubleodd = map (snd . when (odd . fst) (id *** double)) . prefix
您在评论中提到,当双精度数字溢出时,必须将其数字相加。这是我提到的第二个案例,也是简单性本身:

double :: Int -> Int
double = when (>= 10) (sum . digits) . (* 2)
这是您的最终计划:

program = undigits . doubleodd . tail . digits

。。。假设“13到15位数之间”的部分是单独验证的。

缺少的部分是将整数分解为其位数,并从中重新构建的一种方法。这很简单:

digits:: Int -> [Int]
digits = map (`mod` 10) . takeWhile (/= 0) . iterate (`div` 10)

undigits :: [Int] -> Int
undigits = foldr f 0 where f i r = 10 * r + i
然后,看起来您需要以两种不同的方式对这些数字进行后处理,但前提是它们与谓词匹配。让我们为此构建一个组合器:

when :: (a -> Bool) -> (a -> a) -> a -> a
when p f a = if p a then f a else a
第一种情况是在奇数位置(从左到右)输入两位数。同样是琐碎的,有一点小小的不便,
数字
通过增加十的幂来分解数字。让我们以每个数字的位置作为前缀:

prefix :: [Int] -> [(Int, Int)]
prefix is = let n = length is in zip [n, n-1..1] is
双奇数
现在可以表示为

doubleodd :: [Int] -> [Int]
doubleodd = map (snd . when (odd . fst) (id *** double)) . prefix
您在评论中提到,当双精度数字溢出时,必须将其数字相加。这是我提到的第二个案例,也是简单性本身:

double :: Int -> Int
double = when (>= 10) (sum . digits) . (* 2)
这是您的最终计划:

program = undigits . doubleodd . tail . digits

。。。假设“13到15位之间”的部分是单独验证的。

我希望这有帮助,并意识到它可以被清理很多。列表索引以0开始,0也是偶数,是列表的第一个元素。列表理解处理0,2,4。。。第一、第二和第三项

let f n = [mod n 10] ++ f (div n 10)
let r = [if even i then d*2 else d|(i,d)<-zip [0..] (init.reverse.take 14.f$19283828382133)]
sum [b*(10^a)|(a,b) <- zip [12,11..0] r]
设fn=[mod n10]++f(div n10)

让r=[如果偶数为i,则为d*2,否则为d |(i,d)我希望这会有所帮助,并意识到它可以被清理很多。列表索引从0开始,0也是一个偶数,是列表的第一个元素。列表理解处理0,2,4…第一、第二和第三项

let f n = [mod n 10] ++ f (div n 10)
let r = [if even i then d*2 else d|(i,d)<-zip [0..] (init.reverse.take 14.f$19283828382133)]
sum [b*(10^a)|(a,b) <- zip [12,11..0] r]
设fn=[mod n10]++f(div n10)

设r=[如果偶数i然后是d*2,否则是d |(i,d),但是如果奇数大于或等于5,那么会发生什么?从那时起,比“new”数字大于10。这实际上是问题的下一部分。如果你得到10,它会变成1,因为10是1+0,它=1。如果你得到14,它会变成5,因为1+4=5。但是如果奇数大于或等于5,那么会发生什么?从那以后,比“新的”数字大于10。这实际上是问题的下一部分。如果你得到10,它会变成1,因为10是1+0,它=1。如果你得到14,它会变成5,因为你写的很多代码都是直接写在前奏中的。我正在寻找一种更关注loa的方法在包含代码的单个text.hs文件中加载并运行它。感谢最终解决方案
sumdights.mapOdd(*2).init.digits
3/4函数未在
Prelude
中定义。我想你的意思是答案是在ghci会话的上下文中给出的,而不是完整的模块。如果你想要模块,你需要的一切都在那里。不应该
digits 0
给出
[0]
?@Elmex80s为了简单起见,我认为忽略这种情况是合理的。但你是对的。要解决这个问题,你要么需要定义一个包装函数来处理这种情况,要么退回到黑客字符串拆分解决方案:)@JordanMackie如果你想处理这些边缘情况,可能最好实现数字考虑每个数字,然后在wrappe中反转结果