javascript - TypeError: Cannot read property 'toArray' of null at Context.<anonymous> in Typescript -
when try use toarray function newly creates list keep getting error "typeerror: cannot read property 'toarray' of null @ context".
i'm trying create linked list implementation. toarray function must not change i'm pretty sure problem has in reduce function, if not maybe fromarray function
type selector<t> = (head:t, rest?:cons<t>)=> t|cons<t>; type cons<t> = (selector: selector<t>) => t|cons<t>; function cons<t>(head:t, rest?: cons<t>): cons<t> { return (selector: selector<t>) => selector(head, rest); } function head<t>(list:cons<t>):t { return <t>list((head, rest?) => head); } function rest<t>(list:cons<t>):cons<t> { return <cons<t>>list((head, rest?) => rest); } function fromarray<t>(arr:t[]):cons<t>{ function aux(array:t[], i:number):cons<t>{ if(i<array.length){ return cons(array[i], aux(array.slice(i+1), i)) } else{ return null } } return aux(arr, 0); } function reduce<t>(f:(x:t, y:t)=>t, initial:t, list:any):t { if(list){ return reduce(f, f(initial, head(list)), rest(list)); } else{ return initial; } } class list<t> { private head: cons<t>; constructor(list: t[] | cons<t>) { if (list instanceof array) { this.head = fromarray(list); } else { this.head = list; } } toarray(): t[] { return reduce((a,t)=>(a.push(t), a), [], this.head).reverse(); }
you should turn on strictnullchecks
compiler option, since there's lot of undefined
, null
floating around code without flagging errors. main issue here in implementation, empty list undefined
(or maybe null
), , you're not checking in enough places. following debugged being; don't know if bugs gone, toarray()
seems work now. added comments changed things:
type selector<t> = (head: t, rest?: cons<t>) => t | cons<t>; // list can undefined, added it: type cons<t> = undefined | ((selector: selector<t>) => t | cons<t>); function cons<t>(head: t, rest?: cons<t>): cons<t> { return (selector: selector<t>) => selector(head, rest); } // head function guaranteed return t on non-empty list, // overloaded it: function head(list: undefined): undefined; function head<t>(list: cons<t>): t; function head<t>(list: cons<t>): t | undefined { if (!list) return; // watch out empty list return <t>list((head, rest?) => head); } function rest<t>(list: cons<t>): cons<t> { if (!list) return; // watch out empty list return <cons<t>>list((head, rest?) => rest); } function fromarray<t>(arr: t[]): cons<t> { function aux(array: t[], i: number): cons<t> { if (i < array.length) { return cons(array[i], aux(array.slice(i + 1), i)) } else { return; // use undefined instead of null, easier way } } return aux(arr, 0); } // note want reduce return t[] instead of t in toarray() // means f cannot (x:t, y:t) => t. add u parameter // type of initial, return value, , return type of f function reduce<t, u>(f: (x: u, y: t) => u, initial: u, list: cons<t>): u { if (list) { return reduce(f, f(initial, head(list)), rest(list)); } else { return initial; } } class list<t> { private head: cons<t>; constructor(list: t[] | cons<t>) { if (list instanceof array) { this.head = fromarray(list); } else { this.head = list; } } toarray(): t[] { // push puts things @ end; you're trying cons, right? // that's unshift return reduce<t, t[]>((a, t) => (a.unshift(t), a), [], this.head).reverse(); } }
hope helps; luck!
Comments
Post a Comment