【问题标题】:Changing the order of arguments for function and list with flip in haskell使用haskell中的翻转更改函数和列表的参数顺序
【发布时间】:2019-04-25 17:16:55
【问题描述】:

我有以下(来自here):

for_ [1..10] $ (\x -> T.putStrLn $ T.pack $ show x )

我正在尝试用更像这样的方式重写它

applylike myfunction toList

而不是

applylike tolist myfunction

我了解flip function can be employed to change argument order

flip :: (a -> b -> c) -> b -> a -> c

flip f 以 f 的相反顺序获取它的(第一个)两个参数。

>>> flip (++) "hello" "world"
"worldhello"

这是我的原作:

import Data.Foldable (for_)

:t flip
-- 1
for_ [1..10] $ (\x -> T.putStrLn $ T.pack $ show x )
-- success

但是当我尝试直接应用它时,它会失败:

-- 2
flip for_ $ (\x -> T.putStrLn $ T.pack $ show x ) [1..10] 
-- fail

然而,我注意到,如果我删除 (1) 中所需的 $ 运算符,它会成功:

-- 3
flip for_ (\x -> T.putStrLn $ T.pack $ show x ) [1..10] 
-- success

但我不明白为什么扫描正确。当我从原始非翻转版本 (1) 中删除 $ 运算符时,这也会失败。

-- 4    
for_ [1..10] (\x -> T.putStrLn $ T.pack $ show x )
-- fail

如何解析这些 $ 在 (1) 中是必需的,而在 (3) 中不存在?

更新

道歉:4 以上确实成功了。我在调查这个问题时一定有错字,这无疑增加了我的困惑。对于未来的读者,4 不会失败,宇宙更有意义,并且 cmets 和下面接受的答案都对这项调查非常有帮助。

【问题讨论】:

  • 你不想要traverse吗? (Literallyfor_ = flip traverse)。
  • 我可能想这样做,但我也想了解这里的函数应用顺序发生了什么。
  • (4) 对你来说是如何失败的?它在这里工作得很好。
  • 非常彻底的调查!案例 (4) 成功了。
  • 谢谢,我已经添加了更新说明。

标签: haskell


【解决方案1】:

因为这就是 $ 运算符的工作方式。这个操作符不是 Haskell 语法的一部分,而是一个普通的用户定义操作符,和其他操作符一样。它是这样定义的:

f $ x = f x

因此,如果你写这样的东西:

f a $ b

同理:

f a b

但是如果你写这样的东西:

f $ a b

同理:

f (a b)

这是因为函数应用程序a b(即函数a应用于参数b)在Haskell中具有最高优先级,没有比函数应用程序更强大的绑定,包括$运算符。

因此,您的第一次尝试:

flip for_ $ (\x -> T.putStrLn $ T.pack $ show x ) [1..10] 

真的相当于:

flip for_ ( (\x -> T.putStrLn $ T.pack $ show x ) [1..10] )

这显然不是你的意思。

【讨论】:

  • 附注,($) 实际上绑定最弱的:*Main> :i ($) 表示infixr 0 $ 即级别 0,而功能应用程序(即“空格”)绑定在级别 10。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-04-27
  • 2015-05-04
  • 1970-01-01
  • 1970-01-01
  • 2022-12-08
  • 1970-01-01
相关资源
最近更新 更多