2016-02-08 6 views
2

Я пытаюсь выяснить, как реализовать функции сгиба на входах разных типов. В качестве примера я буду использовать функцию count для списка (хотя для этого я имею несколько функций). Предполагая входной список Int (это должно работать с любым типом списка, хотя), мой граф функция будетНесколько типов ввода со сгибом

val count = foldr (fn(x:int,y)=>y+1) 0 ; 
val count = fn : int list -> int 

Однако я пытаюсь сделать функцию подсчета, где тип

val count = fn : int list * bool list -> int 

где список int - это юниверс набора, а bool определяет, какие значения юниверса находятся в наборе. т.е. (1,3,5,6), (true, false, false, true) приводит к окончательному набору (1,6), который будет иметь счет 2. Моя первая мысль попробовать это была в какой-то форме из

val count= foldr (fn(x:(int*bool),y)=>if #2x then y+1 else y) 0 ; 

, но это приводит к возвращаемому типу

val count = fn : (int * bool) list -> int 

, которая не совсем то, что мне нужно. По логике, они похожи, но я должен сгруппировать два типа вместе в одном списке.

ответ

2
  1. Вы можете использовать ListPair.foldl:

    fun count (xs, bs) = ListPair.foldl (fn (x, b, acc) => ...) ... (xs, bs) 
    

    где первая ... некоторая комбинация x, b и acc и второй ... представляет собой первоначальное значение.

    Это предполагает, что xs и bs одинаково длинны, и в случае, если они нет, отбрасывает оставшиеся элементы в более длинном списке. (Вы, вероятно, следует попытаться оправдать, если это дает правильный ответ в любом случае xs или bs длиннее.)

  2. В противном случае, вам нужно объединить (так называемый почтовый индекс) список Int × список BOOL в (int × bool) list, выполнив функцию, которая объединяет два списка, и используйте эту функцию в сочетании со складывающимся вы уже делаете.

    fun combine (x::xs, y::ys) = ... 
        | combine (..., ...) = ... 
    

    Эта функция может быть эквивалентна ListPair.zip.