I’m having trouble with pattern matching with lists in SML. I’m trying to create a function that takes a 2×2 real matrix (defined as 'a list list) and creates a complex (real * real). The matrix is formatted as a list of lists(that are made with reals) with each list being a row. I know that I have to pattern match but I’m unsure how to implement my understanding into actual code. My code thus far is:
fun fromMatrix ((a::M):real matrix) : complex = (hd a, tl M);
I keep getting this error:
stdIn:1.5-13.32 Error: right-hand-side of clause doesn't agree with function result type [tycon mismatch]
expression: real * real list list
result type: complex
in declaration:
fromMatrix =
(fn <pat> :: <pat> : real matrix => (hd <exp>,tl <exp>): complex)
Okay so if
(a::M)has typereal matrix(orreal list list), then that meansa(head) has typereal listandM(tail) has typereal list list. Thenhd ahas typereal, andtl Mhas typereal list list. So putting them together,(hd a, tl M)has typereal * real list list, probably not what you want.You probably want to understand that for lists,
x :: ymeans thatxis the first element, andyis the rest of the list (not the second element), which is a list. Similarly, thehdfunction returns the first element of a list, and thetlfunction returns the rest of the list. If you want to extract the first two elements, you could use the patternx :: y :: z(wherezis the rest of the list after the first 2 elements). If you know it’s going to be a 2-element list, you could matchx :: y :: [], or equivalently,[x, y]. You can nest patterns, so if you have a 2-element list of 2-element lists, you could directly match[[a, b], [c, d]]. However, using a fixed-size list is a sign of bad design. You probably want to use a tuple instead.