在最近的一个风格问题的答案中,我写道
main = untilM (isCorrect 42) (read `liftM` getLine)
Run Code Online (Sandbox Code Playgroud)
和
isCorrect num guess =
case compare num guess of
EQ -> putStrLn "You Win!" >> return True
...
Run Code Online (Sandbox Code Playgroud)
Martijn帮助提出了替代方案:
main = untilM (isCorrect 42) (read <$> getLine)
EQ -> True <$ putStrLn "You Win!"
Run Code Online (Sandbox Code Playgroud)
使用Control.Applicative中的抽象可以使Haskell代码中的哪些常见模式更清晰?有效使用Control.Applicative时要记住哪些有用的经验法则?
查看Ramda.js的来源,特别是"升力"功能.
这是给定的例子:
var madd3 = R.lift(R.curry((a, b, c) => a + b + c));
madd3([1,2,3], [1,2,3], [1]); //=> [3, 4, 5, 4, 5, 6, 5, 6, 7]
Run Code Online (Sandbox Code Playgroud)
因此结果的第一数目是容易的,a,b,和c,是每个阵列的所有的第一元素.第二个对我来说并不容易理解.参数是每个数组的第二个值(2,2,未定义)还是第一个数组的第二个值以及第二个和第三个数组的第一个值?
即使无视这里发生的事情的顺序,我也没有真正看到它的价值.如果我在没有lift它的情况下执行它,我将最终将数组concat作为字符串.这似乎有点像,flatMap但我似乎无法遵循其背后的逻辑.
ZipList附带一个Functor和一个Applicative实例(Control.Applicative),但为什么不选择Alternative?
Bool可通过两种方式幺半群),因此也不应该是的实例我搜索了"实例替代ZipList"(用引号查找代码优先)并且只找到了库,一些教程,讲义而没有实际的实例.
马特芬威克说,如果A是,则ZipList A只会是一个幺半群.看到这里.无论元素类型如何,列表都是幺半群.
AndrewC对同一问题的另一个答案讨论了Alternative实例的外观.他说
Zip有两个合理的选择
[1,3,4] <|> Zip [10,20,30,40]:
Zip [1,3,4]因为它是第一个 - 与Maybe一致Zip [10,20,30,40]因为它是最长的 - 与Zip []丢弃一致
Zip基本上是ZipList.我认为答案应该是Zip [1,3,4,40].我们来看一个实例:
instance Aternative Zip where
empty = Zip []
Zip xs <|> Zip ys = Zip (go xs ys) where
go [] ys = ys
go (x:xs) ys = x : go xs (drop 1 ys)
Run Code Online (Sandbox Code Playgroud)
唯一Zip …
haskell ×3
applicative ×1
coding-style ×1
javascript ×1
lifting ×1
list ×1
ramda.js ×1
typeclass ×1