Это похоже на проблему IDE, я набрал импорт import kotlin.reflect.KFunction1
и ошибка компилятора исчезла.
Однако, если вы добавите выражение / оператор, который возвращает тип KFunction1
, и явно объявите тип, Intellij импортирует его правильно. Например,
"\\s+".toRegex()::matches
Может быть извлечен как
val kFunction1: KFunction1<@ParameterName(name = "input") CharSequence, Boolean> = "\\s+".toRegex()::matches
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.
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;
Краткий ответ: нет. В функциональном программировании вы, как правило, никогда не изменяете переменные, что означает невозможность цикла. Вместо этого вы можете реализовать то же самое, используя рекурсию. Точно так же, поскольку у вас, вообще говоря, нет побочных эффектов, вызовы функций имеют смысл, только если они возвращают данные. Таким образом, бар (материал), вероятно, не очень полезен. Это никак не влияет на остальную часть приложения. В стиле функционального программирования ваша функция bar () должна каждый раз вызываться для разных данных и возвращать то, на что может воздействовать остальная часть приложения.
(ML в некоторых случаях допускает побочные эффекты, но сохраняет вещи просто, давайте пока проигнорируем это)
Чего именно вы пытаетесь достичь? (Что вам нужно зациклить, что делают функции?
Если вы предоставите немного больше деталей, мы можем объяснить более конкретно, как вы должны написать программу. Но в действительности ваша программа просто не имеет смысла в функциональном стиле.
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