如何在ELM中重构此功能?

Sea*_*mpa 4 functional-programming elm

我正在尝试选择函数式编程并决定从Project Euler上的问题1开始:基本上将所有小于1000的数字加上3或5整除(链接:链接).

这是我写的代码.它输出3或5的因子列表(仍需要弄清楚如何求和).

import Html exposing (text)
import Array

main =
  text (
toString
[findSum_maxZ 3 5 1000]
  )

findSum_maxZ x y max_z =
  Array.filter isDivisible_x_or_y (Array.initialize max_z identity)

isDivisible_x_or_y x = 
  if x % 3 == 0 || x % 5 == 0 then True else False
Run Code Online (Sandbox Code Playgroud)

我的问题是我引用了3和5两次,但是我不能用更抽象的'x'和'y'的附加参数调用isDivisible.我的目标是确定删除这些人为可变值的有效方法,以便最终用户只需修改一次输入值.有什么建议?

我很抱歉,如果这个问题很愚蠢,没有很多关于ELM的信息(特别是与我使用过的python,c,c ++,java等相比),我仍然对函数式编程术语不太满意.任何和所有的帮助表示赞赏.

lfa*_*oco 5

关于ML语言的一个很酷的事情是你几乎可以自由地建立自己的"方言"来解决问题.

您可以使用currying仅将xy参数应用于函数,创建一个新函数,其中已经设置了提供的值.

import Html exposing (text)
import Array

main = [findSum 3 5 1000]
           |>toString
           |>text

findSum x y maxZ =
      let
         isDivisibleByX = isDivisible x
         isDivisibleByY = isDivisible y
      in
         Array.initialize maxZ identity
         |>Array.filter isDivisibleByX
         |>Array.filter isDivisibleByY
         --as you can see, it is possible to use a list instead of creating
         --new functions, it is up to you to check which abstraction works
         --the best


isDivisible a b =
      b % a == 0 
Run Code Online (Sandbox Code Playgroud)

您也可以使用单个函数,而无需使用currying:

import Html exposing (text)
import Array

main = [findSum 3 5 1000]
       |>toString
       |>text

findSum x y maxZ =
     Array.initialize maxZ identity
     |>Array.filter (\n-> isDivisible x n ) --or just (isDivisible x)
     |>Array.filter (\n-> isDivisible y n)


isDivisible a b =
  b % a == 0 
Run Code Online (Sandbox Code Playgroud)

如果只想用一行过滤数组,可以这样做:

import Html exposing (text)

main = findSum 3 5 1000
       |>toString
       |>text

findSum x y maxZ =
     let
        divisibles = \n-> isDivisible x n && isDivisible y n
     in
       List.range 0 maxZ 
       |>List.filter divisibles

isDivisible a b =
  b % a == 0 
Run Code Online (Sandbox Code Playgroud)