You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Haskell中如何地道实现两个Maybe Int加1后相乘?能否用do块?

关于Maybe与Monad的问题解答

一、Maybe类型的优雅用法

Haskell里的Maybe本身已经是现成的Monad/Applicative实例,标准库已经帮你实现了所有必要的类型类实例,不需要额外编写代码来让它更易用——直接用就行。所谓“优雅”的写法,取决于场景和你习惯的风格,Monad(比如do块)、Applicative(你当前用的<*>风格)都是合理的选择。

二、用do块实现你的需求

当然可以用do块实现!针对你遇到的Advent of Code问题,do块的写法会更贴近“顺序式逻辑”,可读性很强:

test :: Maybe Int
test = do
  x <- marker1Pos
  y <- marker2Pos
  return $ (x + 1) * (y + 1)

这段代码的逻辑非常直观:

  • 从marker1Pos中取出值x(如果是Nothing,整个do块直接返回Nothing,自动短路)
  • 再从marker2Pos中取出值y(同样,遇到Nothing直接终止)
  • 最后计算(x+1)*(y+1)并包装成Maybe返回

对比你之前的写法:

let test = Just (*) <*> ((+1) <$> marker1Pos) <*> ((+1) <$> marker2Pos)

两种写法都是正确的。do块更偏向“类命令式的可读性”,适合处理有依赖关系的操作;而Applicative风格更紧凑,适合组合独立的操作。你可以根据自己的习惯选择。

补充:Applicative写法的优化

其实你当前的Applicative写法也可以优化得更简洁,比如使用liftA2:

import Control.Applicative (liftA2)

test = liftA2 (*) ((+1) <$> marker1Pos) ((+1) <$> marker2Pos)

或者进一步把(+1)的映射和乘法逻辑合并:

test = liftA2 (\x y -> (x+1)*(y+1)) marker1Pos marker2Pos

这些都是标准库原生支持的写法,不需要自己额外实现功能。

内容的提问来源于stack exchange,提问作者Adam

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 02:50:23