Haskell条件判断函数创建及Python代码转Haskell实现咨询
在Haskell里写带if检查、能返回值的函数
嘿,Haskell里的if和Python不太一样——它是表达式而非语句,天生就能返回值!不过有个小规则:必须带上else分支,因为Haskell是纯函数式语言,得保证不管条件真假,都有明确的返回值,不能像Python那样省略else。
举个直观的例子,写个判断整数奇偶性的函数:
checkEven :: Int -> String checkEven x = if x `mod` 2 == 0 then "Even number!" else "Odd number!"
如果觉得多层if写起来麻烦,还可以用守卫(guard),可读性更强:
checkEven' :: Int -> String checkEven' x | x `mod` 2 == 0 = "Even number!" | otherwise = "Odd number!"
守卫就是把条件写在|后面,otherwise相当于Python里的else,用来兜底所有剩余情况。
把你的Python代码转成Haskell实现
先理清楚你这段Python代码的核心逻辑:处理多组测试用例,每组输入一个n和数组a,生成一个n×n的二维列表lis,其中lis[i][j]的计算规则是:从i到j-1遍历k,如果a[k] < a[j],就取1 + lis[i][k]的最大值,默认值为1;i>j的位置初始为0。
下面是对应的Haskell实现,尽量贴近原逻辑,同时兼顾Haskell的函数式风格:
首先,Haskell处理输入需要用到IO monad,我们先写主函数处理多组输入:
import Data.List (maximum) main :: IO () main = do -- 读取测试用例数量T testCount <- read <$> getLine -- 处理每一组测试用例 mapM_ (\_ -> processTestCase) [1..testCount] processTestCase :: IO () processTestCase = do -- 读取n n <- read <$> getLine -- 读取数组a,和Python的list(map(int, input().split()))功能一致 arr <- map read . words <$> getLine -- 计算核心的二维列表lis let lis = computeLis n arr -- 这里可以根据需求添加结果处理逻辑,比如打印lis print lis
然后是核心的computeLis函数,利用Haskell的惰性求值自动处理依赖,实现动态规划逻辑:
computeLis :: Int -> [Int] -> [[Int]] computeLis n arr = result where -- 定义最终的二维列表result,后续递归引用已计算的值 result = [[getLisVal i j | j <- [0..n-1]] | i <- [0..n-1]] -- 计算lis[i][j]的具体值 getLisVal i j -- 对应Python中i>j时lis[i][j]初始为0 | j < i = 0 -- 当i==j时,值固定为1 | j == i = 1 -- 其他情况按规则计算 | otherwise = -- 收集所有符合a[k] < a[j]的1 + lis[i][k] let validVals = [1 + result !! i !! k | k <- [i..j-1], arr !! k < arr !! j] -- 无符合条件的k时取默认值1,否则取最大值 in if null validVals then 1 else maximum validVals
几个关键细节说明:
- Haskell的列表是0索引,和Python完全一致,直接对应原代码的索引逻辑
result !! i !! k用来获取已计算好的lis[i][k],Haskell的惰性求值会确保在需要时才计算对应的值,避免冗余计算map read . words <$> getLine和Python的list(map(int, input().split()))功能完全匹配,把输入字符串转成整数列表
如果你的代码后续还要补充ans变量的处理逻辑,直接在processTestCase函数里添加对应的逻辑即可。
内容的提问来源于stack exchange,提问作者John Gringus
相关产品推荐
相关产品推荐

