Сумма N чисел
Nov. 28th, 2013 12:00 amОписанная ниже функция add принимает натуральное число n и n интов и возвращает сумму этих интов. Т.е.
add 0 == 0
add 1 42 == 42
add 2 33 44 == 77
add 8 2 2 2 2 2 2 2 2 == 16
Вот так она описывается на Идрисе:
Можно ли ее еще упростить и обойтись без вспомогательной функции adder? Че-то я торможу.
add 0 == 0
add 1 42 == 42
add 2 33 44 == 77
add 8 2 2 2 2 2 2 2 2 == 16
Вот так она описывается на Идрисе:
sumType : Nat -> Type sumType Z = Int sumType (S k) = Int -> sumType k adder : (n:Nat) -> Int -> sumType n adder Z acc = acc adder (S k) acc = \x => adder k (x + acc) add : (n:Nat) -> sumType n add Z = 0 add (S k) = adder k
Можно ли ее еще упростить и обойтись без вспомогательной функции adder? Че-то я торможу.
no subject
Date: 2013-11-27 06:05 pm (UTC)no subject
Date: 2013-11-27 06:07 pm (UTC)add : Int -> (n:Nat) -> sumType n
add acc Z = acc
add acc (S k) = \x => add (x + acc) k
no subject
Date: 2013-11-27 06:47 pm (UTC)no subject
Date: 2013-11-27 06:53 pm (UTC)no subject
Date: 2013-11-27 06:56 pm (UTC)no subject
Date: 2013-11-27 07:06 pm (UTC)извините :)
no subject
Date: 2013-11-27 07:22 pm (UTC)no subject
Date: 2013-11-27 07:47 pm (UTC)no subject
Date: 2013-11-27 09:03 pm (UTC)no subject
Date: 2013-11-27 09:31 pm (UTC)no subject
Date: 2013-11-27 10:31 pm (UTC)monomorphism restriction, впрочем, недалеко ушло...
no subject
Date: 2013-11-27 10:32 pm (UTC)open import Data.Vec open import Data.Vec.N-ary open import Function add : ∀ n → N-ary n ℕ ℕ add n = curryⁿ $ sum {n}Слегка обобщенный sumType - это N-ary, который далее каррируется в вектор и сворачивается библиотечной же sum : ∀ {n} → Vec ℕ n → ℕno subject
Date: 2013-11-27 10:43 pm (UTC)no subject
Date: 2013-11-27 11:19 pm (UTC)no subject
Date: 2013-11-28 02:30 am (UTC)no subject
Date: 2013-11-28 02:32 am (UTC)no subject
Date: 2013-11-28 03:14 am (UTC)no subject
Date: 2013-11-28 03:21 am (UTC)no subject
Date: 2013-11-28 03:39 am (UTC)sumType : Nat -> Type
sumType n = foldr (-> Int) (->) $ replicate n Int
no subject
Date: 2013-11-28 03:53 am (UTC)no subject
Date: 2013-11-28 04:08 am (UTC)int sum(int[] xs ...) { return xs.reduce!"a + b"; }
no subject
Date: 2013-11-28 04:10 am (UTC)no subject
Date: 2013-11-28 04:26 am (UTC)sumType2 : Nat -> Type sumType2 n = foldr f Int $ List.replicate n Int where f a b = a -> bОпределение компиляется и в репле работает, но при попытке использования в коде выше что-то не срастается в унификации.
no subject
Date: 2013-11-28 09:33 am (UTC)Правильный компилятор (tm) должен выполнить статический контроль и сделать fusion.
no subject
Date: 2013-11-28 09:46 am (UTC)no subject
Date: 2013-11-28 10:06 am (UTC)no subject
Date: 2013-11-28 09:07 pm (UTC)no subject
Date: 2013-11-29 02:01 am (UTC)Но все равно не подходит для менее игрушечной задачи, где типы разные.
no subject
Date: 2013-11-29 10:10 am (UTC)add Z = 0
add (S Z) = ((add Z) +) -- could use id; this is a reduction step from a->sumType 0 to sumType 0
add (S k) = \ x y => add k (x + y) -- a general reduction step from b->a->sumType n to b->sumType n, eg k = S n
no subject
Date: 2013-11-29 10:28 am (UTC)Только последняя строчка такая:
add (S (S k)) = \x, y => add (S k) (x + y)
иначе он почему-то не догадывается, что k не Z, и потому не убежден, что add k - функция.
Функция с переменным числом параметров
Date: 2013-11-29 01:03 pm (UTC)no subject
Date: 2013-11-29 01:19 pm (UTC)no subject
Date: 2013-11-30 09:38 am (UTC)folding : ∀ {n A} → (A → A → A) → sumT A (succ n) folding {zero} add z = z folding {(succ n)} add acc = λ x → folding {n} add (add acc x) add : (n : ℕ) → sumT ℕ n add n = folding {n} {ℕ} (_+_) zero- здесь zero добавляется с другого боку. Хотя не соответствует условию "одной функцией", но этот folding уже adder (за вычетом обобщения) (также, тривиально обобщается до "настоящего" фолда с типом функции (B → A → B)no subject
Date: 2013-12-06 09:34 pm (UTC)infoq.com/presentations/scala-idris