Vector products: Difference between revisions

Content added Content deleted
(→‎{{header|Haskell}}: Added a variant based on Either and (>>=) rather than `error`)
Line 1,533: Line 1,533:
** Exception: Dotted Vectors must be of equal dimension.
** Exception: Dotted Vectors must be of equal dimension.
a . d = </pre>
a . d = </pre>


Or using '''Either''' and '''(>>=)''', rather than '''error''', to pass on intelligible messages:

<lang haskell>dotProduct
:: Num a
=> [a] -> [a] -> Either String a
dotProduct xs ys
| length xs /= length ys =
Left "Dot product not defined - vectors differ in dimension."
| otherwise = Right (sum $ zipWith (*) xs ys)

crossProduct
:: Num a
=> [a] -> [a] -> Either String [a]
crossProduct xs ys
| 3 /= length xs || 3 /= length ys =
Left "crossProduct is defined only for 3d vectors."
| otherwise = Right [x2 * y3 - x3 * y2, x3 * y1 - x1 * y3, x1 * y2 - x2 * y1]
where
[x1, x2, x3] = xs
[y1, y2, y3] = ys

scalarTriple
:: Num a
=> [a] -> [a] -> [a] -> Either String a
scalarTriple q r s = crossProduct r s >>= dotProduct q

vectorTriple
:: Num a
=> [a] -> [a] -> [a] -> Either String [a]
vectorTriple q r s = crossProduct r s >>= crossProduct q

-- TEST ---------------------------------------------------
a = [3, 4, 5]

b = [4, 3, 5]

c = [-5, -12, -13]

d = [3, 4, 5, 6]

main :: IO ()
main =
mapM_ putStrLn $
zipWith
(++)
["a . b", "a x b", "a . b x c", "a x b x c", "a . d", "a . (b x d)"]
[ sh $ dotProduct a b
, sh $ crossProduct a b
, sh $ scalarTriple a b c
, sh $ vectorTriple a b c
, sh $ dotProduct a d
, sh $ scalarTriple a b d
]

sh
:: Show a
=> Either String a -> String
sh = either (" => " ++) ((" = " ++) . show)</lang>
{{Out}}
<pre>a . b = 49
a x b = [5,5,-7]
a . b x c = 6
a x b x c = [-267,204,-3]
a . d => Dot product not defined - vectors differ in dimension.
a . (b x d) => crossProduct is defined only for 3d vectors.</pre>


=={{header|Icon}} and {{header|Unicon}}==
=={{header|Icon}} and {{header|Unicon}}==