任何人都知道如何使用部分应用的三参数函数中缀(haskell)

发布于 2024-11-15 18:20:57 字数 288 浏览 2 评论 0原文

我想根据布尔值(参数之一)以不同的方式应用 3 参数函数。

我希望能够以中缀方式应用它,这样我就可以链接它(下面的示例)。类似于以下内容但实际上有效。

f :: Bool -> a -> a -> a

f True  i j = i
f False i j = j

... y `(f True)` z `(f False)` b

我需要将 Bool 作为第二个变量吗?还是别的什么?我有点迷失了。

PS我想这样做的原因是有可选的追加功能

I want to apply a 3 argument function in different ways based on a boolean value (one of the arguments).

I'd like to be able to apply it in an infix manner so I can chain it (example below). something like the following but that actually works.

f :: Bool -> a -> a -> a

f True  i j = i
f False i j = j

... y `(f True)` z `(f False)` b

Do I need to have the Bool as the second variable? Or something else? I'm kind of lost.

P.S. the reason I wanted to do this was to have optional append function

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

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

发布评论

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

评论(5

当爱已成负担 2024-11-22 18:20:57

具有两个以上参数的函数的中缀表示法是可能的,但不是很好。在你的情况下,假设

f :: Bool -> a -> a -> a
f True i j = i
f False i j = j

你可以写

(True `f` 1) 3

它更容易(如其他人的建议)写:

let ft = f True
let ff = f False

那么你可以做

1 `ft` 3 `ff` 5

如果你想使用 f 你应该写:

(False `f` ((True `f` 1) 3)) 5

你可以验证

1 `ft` 3 `ff` 5 == (False `f` ((True `f` 1) 3)) 5

The infix notation for functions with more than two arguments is possible but not very nice. In your case, given

f :: Bool -> a -> a -> a
f True i j = i
f False i j = j

you can write

(True `f` 1) 3

It's much easier (as suggested by others) to write:

let ft = f True
let ff = f False

then you can do

1 `ft` 3 `ff` 5

If you want to use f you should write:

(False `f` ((True `f` 1) 3)) 5

You can verify that

1 `ft` 3 `ff` 5 == (False `f` ((True `f` 1) 3)) 5
各自安好 2024-11-22 18:20:57

您可以使用反向应用运算符来实现类似的效果。但是,对于每个运算符固定性,您都必须定义自己的一对运算符。

这有效:

infixl 5 -|
(-|) :: a -> (a -> b) -> b
(-|) = flip ($)

infixl 5 |-
(|-) :: (a -> b) -> a -> b
(|-) = ($)

infixr 5 =|
(|=) :: (a -> b -> c) -> b -> (a -> c)
(|=) = flip

infixr 5 |=
(=|) :: a -> (a -> c) -> c
(=|) = (-|)

f b x y = if b then x else y

main = do
    putStrLn $ "qwe" -| f True |- "asd" -| f False |- "kojo"
    putStrLn $ "qwe" =| f True |= "asd" =| f False |= "kojo"

并打印:

kojo
qwe

这里 -||- 括号括起左关联中缀表达式以及 =||=< /code> 包含右关联表达式。

请注意,由于这些只是一对独立的运算符,因此误用它们时的错误消息可能会非常模糊。

You can use a reverse application operator to achieve a similar effect. However, for every operator fixity you will have to define its own pair of operators.

This works:

infixl 5 -|
(-|) :: a -> (a -> b) -> b
(-|) = flip ($)

infixl 5 |-
(|-) :: (a -> b) -> a -> b
(|-) = ($)

infixr 5 =|
(|=) :: (a -> b -> c) -> b -> (a -> c)
(|=) = flip

infixr 5 |=
(=|) :: a -> (a -> c) -> c
(=|) = (-|)

f b x y = if b then x else y

main = do
    putStrLn $ "qwe" -| f True |- "asd" -| f False |- "kojo"
    putStrLn $ "qwe" =| f True |= "asd" =| f False |= "kojo"

And prints:

kojo
qwe

Here -| and |- brackets enclose left-associative infix expressions and =| and |= enclose right-associative expressions.

Be wary that as those are just pairs of independent operators, error messages when misusing them may be quite obscure.

街角迷惘 2024-11-22 18:20:57

虽然已经提出了中缀表达式语法,但据我所知,它们尚未被采用。

您可以考虑使用 if then else 三元函数,如下所示:

infix 0 ?
(?) :: Bool -> (t, t) -> t
c ? (t, e) = if c then t else e

While infix expression syntax have been proposed, they have not been adopted, to the best of my knowledge.

You might consider using if then else ternary functions, like so:

infix 0 ?
(?) :: Bool -> (t, t) -> t
c ? (t, e) = if c then t else e
挖鼻大婶 2024-11-22 18:20:57

嗯,一方面,f 的类型为 f :: Bool ->一个->一个-> a

请参阅http://www.haskell.org/haskellwiki/Infix_operator#Using_prefix_functions_with_infix_notation 有关在中缀设置中使用前缀函数的更多信息。

希望其他人更聪明,可以解释为什么

1 `f True` 3 

不起作用,因为

ft = f True
1 `ft` 3

工作正常,这似乎违反了引用透明度......

似乎没有一个“好的”,简单的方法来做到这一点,但我'我确信有一些更高级别的模式适合,或者您可以使用例如 zipWith 或 Folds 做一些事情...

Well, for one thing, f would have type f :: Bool -> a -> a -> a

See http://www.haskell.org/haskellwiki/Infix_operator#Using_prefix_functions_with_infix_notation for more information on using prefix functions in an infix setting.

Hopefully somebody else is wiser and can explain why

1 `f True` 3 

doesn't work, since

ft = f True
1 `ft` 3

works fine, and this seems to violate referential transparency...

It would seem that there isn't a "nice", easy way to do this, but I'm sure there's some higher level pattern that this fits, or you could do something with, e.g., zipWith or folds...

蓝颜夕 2024-11-22 18:20:57

为什么你需要布尔函数?如果从未使用过该值,为什么不将 f 定义为

f :: a -> a -> a  
f i j  
i `f` j

如果确实需要布尔值,则按照 Pvital 的建议,创建 ftrue 和 ffalse 并使用它们。

Why do you need the boolean function at all? If the value is never used, why not define f as

f :: a -> a -> a  
f i j  
i `f` j

If the boolean is really needed, then as Pvital suggested, create a ftrue and ffalse and use those.

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