尝试写一个免费的功能点,GHCI不批准

发布于 2024-12-23 05:50:12 字数 1030 浏览 1 评论 0原文

作为练习,我尝试手动实现前奏中有趣的部分。每当我发现一个免费得分的机会时,我都会抓住它。然而,这让我在最不可能的地方遇到了一堵砖墙。使用此代码:

myelem _ [] = False 
myelem x y  = if x == head y then True else myelem x (tail y)

我正在尝试实现 notElem。这是我的尝试:

-- First
mynotelem = not myelem

可以理解的是,由于类型不匹配而导致崩溃。这很容易修复:

-- Second
mynotelem x y = not (myelem x y)

然而,参数 x 和 y 的显式声明感觉很丑陋且不必要,所以我尝试将其恢复为点自由风格。

-- Third
mynotelem = not $ myelem

公平地说,这失败了

 Couldn't match expected type `Bool'
         with actual type `a0 -> [a0] -> Bool'
 In the second argument of `($)', namely `myelem'
 In the expression: not $ myelem
 In an equation for `mynotelem': mynotelem = not $ myelem

,类型仍然不匹配。但如何解决呢?同样,您可以直接跳到

-- Fourth
mynotelem x y = not $ myelem x y

“哪个有效”,但似乎很危险地接近于原地踏步。我发现可以消除其中一个论点:

-- Fifth
mynotelem x = not . (myelem x)

但是那个讨厌的 x 仍然存在。我该如何消除它?

As an exercise I'm trying to implement interesting parts of the prelude manually. Whenever I spot an opportunity to go point free I take it. However this has led me to a brick wall in the most unlikely place. Using this code:

myelem _ [] = False 
myelem x y  = if x == head y then True else myelem x (tail y)

I am trying to implement notElem. Here are my attempts:

-- First
mynotelem = not myelem

Understandably blows up due to the types not matching up. This is easily fixed:

-- Second
mynotelem x y = not (myelem x y)

However the explicit declaration of arguments x and y feels ugly and unnecessary, so I try to get it back into point free style.

-- Third
mynotelem = not $ myelem

Which fails with

 Couldn't match expected type `Bool'
         with actual type `a0 -> [a0] -> Bool'
 In the second argument of `($)', namely `myelem'
 In the expression: not $ myelem
 In an equation for `mynotelem': mynotelem = not $ myelem

Fair enough, the types still don't match up. But how do you fix it? Again you can jump straight to

-- Fourth
mynotelem x y = not $ myelem x y

Which works, but seems dangerously close to just going in circles. I discover it's possible to eliminate one of the arguments:

-- Fifth
mynotelem x = not . (myelem x)

But that pesky x still remains. How do I eliminate it?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

只为守护你 2024-12-30 05:50:12

我们可以这样重写您的代码:

mynotelem x = not . (myelem x)
            = (not .) (myelem x)

现在认识到这只是 hx = f (gx) 以及 f = (not .)g = myelem code>,因此我们可以使用 (.) 运算符将其编写为无点的,如 h = f 。 g

mynotelem = (not .) . myelem

注意当与具有更多参数的函数组合时,模式如何继续:

> let f x y z = x+y+z
> (((sqrt .) .) . f) 1 2 3
2.449489742783178

或者,您也可以使用这种看起来有趣的组合运算符组合来编写它:

mynotelem = ((.).(.)) not myelem

对于更多参数,模式继续如下:

> ((.).(.).(.)) sqrt f 1 2 3
2.449489742783178

We can rewrite your code like this:

mynotelem x = not . (myelem x)
            = (not .) (myelem x)

Now recognize that this is just h x = f (g x) with f = (not .) and g = myelem, so we can write it point-free with another use of the (.) operator as h = f . g:

mynotelem = (not .) . myelem

Note how the pattern continues when composing with functions with more arguments:

> let f x y z = x+y+z
> (((sqrt .) .) . f) 1 2 3
2.449489742783178

Alternatively, you can also write it with this funny-looking composition of composition operators:

mynotelem = ((.).(.)) not myelem

For more arguments, the pattern continues like this:

> ((.).(.).(.)) sqrt f 1 2 3
2.449489742783178
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文