在F#中没有参数的Lambda表达式

时间:2018-02-03 15:02:48

标签: c# lambda f#

我试图将以下C#代码转换为F#:

UIView.Animate (2, 0, UIViewAnimationOptions.CurveEaseInOut,
            () => {
                imageView.Center =
                    new CGPoint (UIScreen.MainScreen.Bounds.Right - imageView.Frame.Width / 2, imageView.Center.Y);},
            () => {
                imageView.Center = pt; }
        );

它调用UIView.Animate并传递动画代码和动画完成代码的持续时间,延迟,动画选项和lambda表达式。

我知道F#中的lambda表达式使用fun语法。这是我的尝试:

        UIView.Animate(0,UIViewAnimationOptions.CurveEaseOut, fun ->
        {
           //first code section
        },
        fun -> 
        {
            //second code section
        }

    )

但我不认为我这样做是正确的,因为它会引发语法错误unexpected symbol -> in lambda expression

编辑:

这是我的代码片段,它是嵌套在另一个动画中的动画。我得到的错误是The method or object Animate does not take 4 arguments, a method or overload was found taking two arguments。我尝试删除fun块之间的逗号,然后它抱怨缩进。

UIView.Animate(0,UIViewAnimationOptions.CurveEaseOut, (fun () ->

           x.View.LayoutIfNeeded()),
        fun () -> (

            let height : nfloat = Conversions.nfloat(220)
            let animationDuration = (userInfo.[UIKeyboard.AnimationDurationUserInfoKey] :?> NSNumber).FloatValue
            let animationOptions = (userInfo.[UIKeyboard.AnimationCurveUserInfoKey] :?> NSNumber).UintValue

            let window = UIApplication.SharedApplication.KeyWindow
            if window <> null then 
                if isKeyboardShowing then 
                    Console.WriteLine("Completed")
                    let y = window.Frame.Height
                    UIView.Animate(new TimeInterval(animationDuration),UIViewAnimationOptions(animationOptions), fun () ->
                       bottomView.Frame <- CGRect(0,y,bottomView.Frame.Width,bottomView.Frame.Height)
                       fun () ->
                            Console.WriteLine("Completed")
                   )

    ))

2 个答案:

答案 0 :(得分:2)

你只是错过了lambda的参数部分:

fun () -> <function body goes here>

在您的情况下,您需要一个不带参数的函数,因此我们只需将()放到unit

...Animate(0, UIViewAnimationOptions.CurveEaseOut, (fun () -> do something), (fun () -> do something))

<强>更新 这很难说,因为我无法重现您的环境,但我尝试用我最好的猜测重新格式化您的代码示例:

UIView.Animate(
  0,
  0, // you might be missing an argument here?
  UIViewAnimationOptions.CurveEaseOut,
  (fun () -> x.View.LayoutIfNeeded()),
  (fun () ->
      let height : nfloat = Conversions.nfloat(220)
      let animationDuration = (userInfo.[UIKeyboard.AnimationDurationUserInfoKey] :?> NSNumber).FloatValue
      let animationOptions = (userInfo.[UIKeyboard.AnimationCurveUserInfoKey] :?> NSNumber).UintValue

      let window = UIApplication.SharedApplication.KeyWindow
      if window <> null and isKeyboardShowing then 
          Console.WriteLine("Completed")
          let y = window.Frame.Height
          UIView.Animate(
            new TimeInterval(animationDuration),
            UIViewAnimationOptions(animationOptions),
            (fun () -> bottomView.Frame <- CGRect(0, y, bottomView.Frame.Width, bottomView.Frame.Height)),
            (fun () -> Console.WriteLine("Completed")))))

这段代码变得越来越笨重,所以我建议为回调定义单独的函数,这样可以更容易阅读/格式化。此外,根据Xamarin docs,似乎没有UIView.Animate的4参数版本。您可能错过了durationdelay参数?

答案 1 :(得分:2)

关于逗号问题:

在F#语法中,逗号不表示lambda表达式的结束,因此使用以下表达式:

fun x -> a, fun y -> b

将被解析为:

fun x -> (a, fun y -> b)

也就是说,它不会被理解为用逗号分隔的两个lambda,而是作为返回元组的单个lambda。

要使它成为两个lambda,请使用括号:

(fun x -> a), (fun y -> b)