So I have a function which shifts some ternary values in an array by the desired amount, but when I shift any array, (b) value(s) (on the right if shifting left, and the left if shifting right) will always be replaced with null. Here's my code:
let ( <<| ) (a:FalseTrit[]) (b:int) =
array.Copy(a, b, a, 0, a.Length - 1)
array.Clear(a, a.Length - b, b)
let ( |>> ) (a:FalseTrit[]) (b:int) =
array.Copy(a, 0, a, b, a.Length - b)
array.Clear(a, 0, b)
I couldn't find any answers on the internet. Is there a better way to do this, or something I did wrong? Thanks in advance.
Array.Clear
sets a range of elements in an array to the default value of each element type (see docs ).
Since FalseTrit
is a reference type and not a value type, it has default value null
.
Expanding on the comment by Alexey Romanov why you should prefer standard library functions from Microsoft.FSharp.Collections.Array
module over instance members of System.Array
: Type inference makes them easier to use and curried arguments prettier.
While the documentation for Array.blit
misses the assurance of System.Array.Copy
in regard of arrays overlapping, I strongly suspect the same applies because of its underlying implementation:
If sourceArray and destinationArray overlap, this method behaves as if the original values of sourceArray were preserved in a temporary location before destinationArray is overwritten.
let (<<|) a b =
Array.blit a b a 0 (Array.length a - b)
Array.fill a (Array.length a - b) b Unchecked.defaultof<_>
// val ( <<| ) : a:'a [] -> b:int -> unit
let (|>>) a b =
Array.blit a 0 a b (Array.length a - b)
Array.fill a 0 b Unchecked.defaultof<_>
// val ( |>> ) : a:'a [] -> b:int -> unit
Here, the behavior of the original code is kept: Unchecked.defaultof
will return null
for reference types.
On a stylistic note, consider replacing the code by a generator expression returning a fresh array, because mutation is not seen as functional best practice, and neither are custom operators returning unit
.
let (<<|) a b = [|
for i in b..Array.length a - 1 + b ->
if i < Array.length a then a.[i]
else Unchecked.defaultof<_> |]
// val ( <<| ) : a:'a [] -> b:int -> 'a []
let (|>>) a b = [|
for i in -b..Array.length a - 1 - b ->
if i < 0 then Unchecked.defaultof<_>
else a.[i] |]
// val ( |>> ) : a:'a [] -> b:int -> 'a []
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.