In F # there are many different lists / types of collections.
F # list As Chris said, you cannot initialize a recursive value of this type, because the type is not lazy and not changed (immutability means you need to create it immediately, and the fact that it is not lazy means you cannot use recursive F # values using let rec ). As ssp said, you can use Reflection to hack it, but this is probably the case we don't want to discuss.
The other type is seq (actually IEnumerable ) or the LazyList type from PowerPack. They are lazy, so you can use let rec to create a circular value. However (as far as I know), none of the functions working with them takes into account circular lists - if you create a circular list, it simply means that you create an infinite list, so the result (for example) of the map will be a potentially infinite list.
Here is an example for a LazyList type:
#r "FSharp.PowerPack.dll"
The question is what data types you can define yourself. Chris shows the modified list, and if you write operations that modify it, they affect the entire list (if you interpret it as an infinite data structure).
You can also define a lazy (potentially circular) data type and implement operations that process loops, so when you create a circular list and project it into another list, it will create a circular list (rather than a potentially infinite data structure).
A type declaration may look like this (I use an object type, so that we can use reference equality when checking for loops):
type CyclicListValue<'a> = Nil | Cons of 'a * Lazy<CyclicList<'a>> and CyclicList<'a>(value:CyclicListValue<'a>) = member x.Value = value
The following map function handles loops - if you give it a loop list, it will return a newly created list with the same loop structure:
let map f (cl:CyclicList<_>) =
Tomas petricek
source share