繁体   English   中英

我如何以无点样式重写这个回文验证器?

[英]How would I rewrite this palindrome verifier in point-free style?

我有这段代码:

palindrome :: String -> Bool
palindrome x = x == reverse x

有没有办法以无点的方式重写这个?

是的,因为任何函数都可以用无点样式编写。 这里, (->) r (又名读者)的Applicative实例为你做了这个,因为

(f <*> g) x = f x (g x)

您可能会将此识别为SKI演算中的S组合子(顺便说一下, return K)。

你的Palindrome检查器写成

x == reverse x

以中缀形式读取

(==) x (reverse x)

并且通过与上面的<*>定义进行比较,这导致表达式

isPalindrome x = ((==) <*> reverse) x

您可以在哪里删除尾随x以获得解决方案

isPalindrome = (==) <*> reverse

这可能不如原始表达式可读,因此不应该使用。 无点样式是为了便于阅读,仅在certian情况下有用。

你可能认为这种方法是作弊的:

palindrome :: Eq a => [a] -> Bool
palindrome = palindrome'
  where palindrome' xs = xs == reverse xs

当然,大卫和弗雷尔也提出了适用的风格:

palindrome'' :: Eq a => [a] -> Bool
palindrome'' = (==) <*> reverse

但这个表达怎么样呢?

palindrome''' :: Eq a => [a] -> Bool
palindrome''' = (foldl (\b (x, y) -> b && x == y) True)
              . (uncurry zip)
              . reverse'
  where reverse' xs = (xs, reverse xs)

(->) r也是一个Monad,所以你的回文检查器可以用monadic bind编写,这可能比上面的Applicative解决方案更具可读性

palindrome :: String -> Bool
palindrome = reverse >>= (==)

是。

palindrome :: String -> Bool
palindrome = ap (==) reverse
 palindrome :: String -> Bool
 palindrome = uncurry (==) . (id &&& reverse)

(&&&)Control.Arrow中定义,以便(f &&& g) x = (fx, gx)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM