Skip to content

Instantly share code, notes, and snippets.

@oisdk
Last active April 29, 2026 07:47
Show Gist options
  • Select an option

  • Save oisdk/67714b0e02259e972fa5e06071ab7c5e to your computer and use it in GitHub Desktop.

Select an option

Save oisdk/67714b0e02259e972fa5e06071ab7c5e to your computer and use it in GitHub Desktop.
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE FunctionalDependencies #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE UndecidableInstances #-}
import Control.Applicative (liftA2)
type Polynomial = [Rational]
instance Num a => Num [a] where
fromInteger = pure . fromInteger
[] + ys = ys
xs + [] = xs
(x:xs) + (y:ys) = (x+y) : (xs + ys)
[] * _ = []
(x:xs) * ys = map (x*) ys + (0 : (xs * ys))
abs = map abs
signum = map signum . take 1
negate = map negate
eval :: Num a => [a] -> a -> a
eval xs x = foldr (\a s -> a + x * s) 0 xs
type TwoVar = [Polynomial]
eval2 :: TwoVar -> Rational -> Rational -> Rational
eval2 p x y = eval (eval p [x]) y
var :: Num a => [a]
var = [0,1]
x = var
y = [var]
poly = 2 * x ^ 2 - y ^ 3 + 4
-- >>> poly
-- [[4,0,0,-1],[0],[2]]
-- >>> eval2 poly 2 3
-- -15
instance Num n => Num (e -> n) where
fromInteger = const . fromInteger
(f + g) x = f x + g x
(f * g) x = f x * g x
abs = (abs .)
signum = (signum .)
negate = (negate .)
class Num r => Poly p r | p -> r, r -> p where
evalN :: p -> r
instance Poly Integer Integer where
evalN = id
instance Poly p r => Poly [p] (Integer -> r) where
evalN xs x = foldr (\a s -> evalN a + fromInteger x * s) 0 xs
-- >>> evalN poly 2 3
-- -15
z = [[var]]
-- >>> evalN (poly + z) 2 3 1
-- -14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment