现在有几次,我发现自己定义了:
(<?>) :: [a] -> [a] -> [a]
[] <?> ys = ys
xs <?> _ = xs
Run Code Online (Sandbox Code Playgroud)
当然,这是一个关联操作,空列表[]
既是左标识又是右标识。它的功能类似于 Python 的or
.
在我看来,这会是一个很好的(<|>)
,比原来更好的(++)
。选择第一个非空列表感觉更像是我对命名类型类的期望,Alternative
而不是连接列表。诚然,它不太合适MonadPlus
,但我认为为救赎付出的代价很小。我们已经在标准库中拥有(++)
和;(<>)
我们是否需要另一个同义词,或者一个新函数(据我所知)会更有帮助吗?
我起初认为这可能是一个很好的Alternative
例子,但在相关问题的答案ZipList
之后的讨论让我相信了事实并非如此。除了向后兼容性和保持明智之外,当前实例而不是这个新实例还有什么理由呢?MonadPlus
如何使用Reader
/ ReaderT
来ask
获取列表类型,例如[(Int, Int)]
然后在列表monad中执行计算(属于ask
ed 的类型)?
我的破解代码如下,为了清楚起见缩短了:
attempt :: Int -> Int -> ReaderT [(Int,Int)] [] [[Int]]
attempt start end =
do (s0, e0) <- ask
return [0]
Run Code Online (Sandbox Code Playgroud)
为了让您了解我正在尝试做什么,这里是相同的功能,使用列表monad而不是Reader:
paths :: [(Int, Int)] -> Int -> Int -> [[Int]]
paths edges start end =
if start == end
then return [end]
else do (s0, e0) <- edges
guard $ s0 == start
subpath <- paths edges e0 end
return $ s0 : subpath …
Run Code Online (Sandbox Code Playgroud)