Циклы в SML/NJ

Это похоже на проблему IDE, я набрал импорт import kotlin.reflect.KFunction1 и ошибка компилятора исчезла.

Однако, если вы добавите выражение / оператор, который возвращает тип KFunction1, и явно объявите тип, Intellij импортирует его правильно. Например,

"\\s+".toRegex()::matches

Может быть извлечен как

val kFunction1: KFunction1<@ParameterName(name = "input") CharSequence, Boolean> = "\\s+".toRegex()::matches
5
задан Norman Ramsey 3 May 2009 в 23:38
поделиться

4 ответа

In a functional program, a mutable variable turns into a parameter, typically to a nested helper function.

Since in your example, the thing being mutated is aleady parameter, no helper function is needed. Your code becomes

fun foo stuff counter =
  if counter > 0 then
    ( bar stuff
    ; foo stuff (counter-1)
    )
  else
    ()

Of course this code is still terribly imperative... The call bar stuff is executed purely for side effect. Not very ML-ish.

6
ответ дан 18 December 2019 в 07:56
поделиться

I agree with the other contributors that you should generally use recursion instead of loops and mutation to do this in a functional language.

If you really wanted to use mutation and loops though, you would need to use a data structure called a reference which is a kind of "mutable cell". You allocate the reference with the ref function, passing it the initial contents. You access the contents using the ! operator. And you set new contents using the := operator. So the literal translation of your code above would be something like the following. As you can see, the syntax is really ugly and that is another reason why people avoid it.

fun foo (stuff, counter_start) =
let
  val counter = ref counter_start
in
  while !counter > 0 do (
    bar stuff;
    counter := !counter - 1
  )
end;
7
ответ дан 18 December 2019 в 07:56
поделиться

Краткий ответ: нет. В функциональном программировании вы, как правило, никогда не изменяете переменные, что означает невозможность цикла. Вместо этого вы можете реализовать то же самое, используя рекурсию. Точно так же, поскольку у вас, вообще говоря, нет побочных эффектов, вызовы функций имеют смысл, только если они возвращают данные. Таким образом, бар (материал), вероятно, не очень полезен. Это никак не влияет на остальную часть приложения. В стиле функционального программирования ваша функция bar () должна каждый раз вызываться для разных данных и возвращать то, на что может воздействовать остальная часть приложения.

(ML в некоторых случаях допускает побочные эффекты, но сохраняет вещи просто, давайте пока проигнорируем это)

Чего именно вы пытаетесь достичь? (Что вам нужно зациклить, что делают функции?

Если вы предоставите немного больше деталей, мы можем объяснить более конкретно, как вы должны написать программу. Но в действительности ваша программа просто не имеет смысла в функциональном стиле.

5
ответ дан 18 December 2019 в 07:56
поделиться

I don't know ML, but this is some ML-like pseudo code:

fun foo stuff 0 = return ()
  | foo stuff counter = (bar stuff; foo stuff (counter - 1))

I don't know how to "chain" commands in ML; the semicolon is just a placeholder.

Generally, you wouldn't loop. I would rather expect the usual higher order functions. When you get used to those, manually writing a loop will feel like coding assembler.

edit: fixed code according to comment

2
ответ дан 18 December 2019 в 07:56
поделиться
Другие вопросы по тегам:

Похожие вопросы: