Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

(Seq|List).fold produces incorrect output when state is a function with arity > 1 #2035

Closed
felixschorer opened this issue Apr 27, 2020 · 2 comments

Comments

@felixschorer
Copy link

felixschorer commented Apr 27, 2020

Description

Seq.fold and List.fold produce incorrect output when state is a function with arity greater than 1.

List.fold
val fold : folder:('State -> 'T -> 'State) -> state:'State -> list:'T list -> 'State

Repro code

let folder state value x y = value :: state x y
let state x y = [x; y]
let d = Seq.fold folder state [0..3]
printfn "%A" (d 42 42)

Repl link

Expected and actual results

Expected output: [3; 2; 1; 0; 42; 42]
Actual output: [3]
The tail of the resulting List is a function instead of an other List.

Related information

  • Fable version: 2.8.2
  • Operating system: Windows 10 Pro 1903
@felixschorer
Copy link
Author

felixschorer commented Apr 28, 2020

I stepped through the generated JS. The problem seems to be here:

export function folder(state$$1, value, x, y) {
  return new List(value, state$$1(x, y));
}

state$$1 is a curried function, but is called as an uncurried function.


This works:

export function folder(state$$1, value, x, y) {
  return new List(value, state$$1(x)(y));
}

@ncave
Copy link
Collaborator

ncave commented Apr 28, 2020

Yes, the problem seems to be that the F# compiler wraps the state parameter in a curried lambda wrapper, which is not uncurried by Fable.
Here it is in a different form:

let inline folder st value x y = value :: st x y
let state x y = [x; y]
let d = List.fold folder state [0;1;2;3]
System.Console.WriteLine(List.length (d 42 42))

compiles to:

import { length, fold, ofArray } from "fable-library/List.js";
import { List } from "fable-library/Types.js";
export function state(x, y) {
  return ofArray([x, y]);
}
export const d = fold(function (st, value) {
  return function (x$$1) {
    return function (y$$1) {
      return new List(value, st(x$$1, y$$1));
    };
  };
}, function (x$$3) {
  return function (y$$3) {
    return state(x$$3, y$$3);
  };
}, ofArray([0, 1, 2, 3]));
console.log(length(d(42)(42)));

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants