2010-05-08 3 views
6

Это не очень важная проблема, но я хотел бы увидеть пример tacit programming в F #, где мои точечные могут иметь несколько аргументов (не в виде списка или кортежа) ,Непосредственный стиль программирования с использованием F #

А во-вторых, как такие функции могут манипулировать сложной структурой данных . Я пытаюсь в F # Interactive, но пока не добился успеха.

Я пытался, например:

> (fun _ -> (fun _ -> (+))) 333 222 111 555 

Это правильно?

И:

> (fun _ -> (fun _ -> (+))) "a" "b" "c" "d";; 

val it : string = "cd" 
+3

Вы должны использовать «point-free», а не «бессмысленно». Это стандартный термин. :) –

ответ

4

F # не содержит некоторые из основных функций, которые доступны в Haskell (в основном потому, что F # программисты обычно предпочитают явный стиль программирования и использовать стиль pointfree только в самых очевидных случаях , где это не ухудшает читаемость).

Однако вы можете определить несколько основных комбинаторов, как это:

// turns curried function into non-curried function and back 
let curry f (a, b) = f a b 
let uncurry f a b = f (a, b) 

// applies the function to the first/second element of a tuple 
let first f (a, b) = (f a, b) 
let second f (a, b) = (a, f b) 

Теперь вы можете реализовать функцию для добавления длины двух строк с помощью комбинаторов следующим образом:

let addLengths = 
    uncurry (((first String.length) >> (second String.length)) >> (curry (+))) 

Это создает две функции которые применяют String.length к первому/второму элементу кортежа, затем записывает их, а затем добавляет элементы кортежа, используя +. Все дело обернуто в uncurry, поэтому вы получаете функцию типа string -> string -> int.

+0

Я проверил это в FSI, и он работает! Большое спасибо; Кстати, не могли бы вы объяснить, как вы попали в синтаксис композиции? Я имею в виду '(first String.length) >> (second String.length)' Это выглядит несколько необычно для меня;) – Bubba88

+0

Это достигается с помощью композиции функций '>>'. Например, 'f >> g' означает, что для аргумента' x' он будет вызывать 'g (f (x))'. В приведенном выше примере первая функция ('first String.length') превращает кортеж' string * string' в строку tuple 'int *, а вторая функция (' second String.length') превращает это в 'int * int ', содержащий длины. –

+0

Вы практически реализуете стрелки для F #;) Ладно, почему бы и нет - стрелы были изобретены как комбинация монадов и негласное программирование. – Dario

2

В F #, арностью функций фиксирована, так что вы не собираетесь быть в состоянии написать как

(op) 1 2 

и

(op) 1 2 3 4 

для любого данного оператора op. Вам нужно будет использовать список или другую структуру данных, если это то, что вы хотите. Если вы просто пытаетесь избежать именованных переменных, вы всегда можете сделать «1 + 2 + 3 + 4». Самый идиоматический способ добавления списка чисел в F # - List.sum [1;2;3;4], который также позволяет избежать переменных.