У меня есть две аналогичные функции nested
и nestedCurried
, которые пересекают дерево XML с XLinq. Они не делают ничего полезного - это просто «сжатый» отрывок из более сложного кода.F # XLinq traversal - curried version of functions throws StackOverflowException
То, что я бы ожидать от этих двух функций вести себя таким же образом, как и для меня это выглядит как они идентичны, с той лишь разницей, в nestedCurried
не явно объявлять e: XElement
аргумент - это curied за счет использования elements
из функции и функции композиции >>
Между тем, функция nestedCurried
бросает StackOverflowException
при вызове на любом XElement
оценена в FSI:
#r "System.Xml.Linq"
open System.Xml.Linq
let inline elements (e: XElement) = e.Elements() |> Seq.toList
let rec nested() e = elements e |> List.collect (nested())
let rec nestedCurried() = elements >> List.collect (nestedCurried())
let x = XDocument.Parse """<a></a>"""
let ok : XElement list = nested() (x.Root)
// Stack Overflow below
let boom : XElement list = nestedCurried() (x.Root)
Почему возникает StackOverflowException
, какова техническая разница между этими двумя функциями, и как я могу объявить функцию nested
без указания аргумента XElement
явно?
ok Я думаю, что знаю, моя первоначальная мысль заключалась в том, что эти две функции эквивалентны поведению - но они не являются , Правильно ли я понимаю, что если бы F # оценивалась лениво, то исключение не произошло бы? – theimowski
Да, это правильно. –