简体   繁体   中英

Lambda Expressions with no arguments in F#

I'm trying to convert the following C# code into 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; }
        );

It calls UIView.Animate and passes the duration, delay, animation options, and lambda expressions for the animation code and animation completion code.

I know that lambda expressions in F# use the fun syntax. This is my attempt:

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

    )

but I don't think I'm doing this right as it throws a syntax error unexpected symbol -> in lambda expression .

EDIT:

This is my code snippet, its a animation nested within another animation. The error I'm getting is The method or object Animate does not take 4 arguments, a method or overload was found taking two arguments . I tried removing the commas between the fun blocks, however then it complains about indentation.

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")
                   )

    ))

You're just missing the argument part of your lambda:

fun () -> <function body goes here>

It looks like in your case you need a function that takes no args, so we just put () for unit .

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

Update It's hard to say because I can't reproduce your environment, but I've tried to reformat your code sample with my best guess:

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")))))

This piece of code is growing unwieldy, so I'd recommend defining separate functions for the callbacks which should make it easier to read/format. Also, there really doesn't appear to be a 4-argument version of UIView.Animate according to Xamarin docs . You might be missing a duration or delay argument?

Regarding the comma problem:

In F# syntax, the comma does not indicate the end of a lambda expression, so the following expression:

fun x -> a, fun y -> b

would be parsed as:

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

that is, it would be understood not as two lambdas separated by a comma, but as a single lambda that returns a tuple.

To make it two lambdas, use parentheses:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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