3622
правки
Изменения
→Пример
</code>
Запишем уравнение типа для него: <tex> f(a) = a \cdot f(a) \cdot a + f(a) + a \cdot a \cdot a\ (1)</tex>. На самом деле порядок аргументов в типе не очень важен, мы сами его задаём, поэтому можно написать чуть более сокращенную запись:
На самом деле порядок аргументов в типе не очень важен, мы сами его задаём, поэтому можно написать чуть более сокращенную запись: <tex> f(a) = a^2 \cdot f(a) + f(a) + a^3 </tex>
Забудем на некоторое время, что мы работаем с типами. Продифференцируем обе части уравнение по переменной <tex> a </tex>, получим линейное уравнение относительно производной, а затем выразим её.
<tex> f'(a) = 2a \cdot f(a) + a^2 \cdot f'(a) + f'(a) + 3a^2 </tex> <tex> f'(a) = \dfrac{2a \cdot f(a) + 3a^2}{1 - (a^2 + 1)} = (2a \cdot f(a) + 3a^2) \cdot \dfrac{1}{1 - (a^2 + 1)} \ (2)</tex> В итоге у нас производная является произведением двух функций, а для типа это значит, что он является произведением двух типов. При умножении на константу у нас будет просто несколько одинаковых конструкторов с разными именами, поэтому распишем типа для первой скобки:<code> <font color=green>--сначала распишем производную типа, полученного сразу после дифференцирования (1), если всё аккуратно раскрыть</font> '''data''' DMice a = S (Mice a) a | H a (DMice a) a | M a (Mice a) | Y (DMice a) | A a a | K a a | Shmyak a a</code>
Теперь распишем первую скобку в (2):
<code>
'''data''' DMice' = M1 a (Mice a) | M2 a (Mice a) | C1 a a | C2 a a | C3 a a
</code>
Дальше идёт дробь. Вспоминаем, что на самом деле ей отвечает тип <tex> L(a^2 + 1) </tex>.
Поэтому получаем в итоге:
<code>
'''data''' DMiceListElem a = DM1 a a | DM0
'''data''' DMiceList a = MNil | MCons (DMiceListElem a) (DMiceList a)
'''data''' ZMice a = ZMice a (DMice' a) (DMiceList a)
</code>
* [http://learnyouahaskell.com/zippers LearnYourHaskell {{---}} Zippers]
* [http://sprunge.us/HCDN Пример zipper'a из кр]