Skip to content

Instantly share code, notes, and snippets.

@cjlarose
Last active July 4, 2016 21:57
Show Gist options
  • Save cjlarose/b1a25cc1e8e6165342506faa15d6cd65 to your computer and use it in GitHub Desktop.
Save cjlarose/b1a25cc1e8e6165342506faa15d6cd65 to your computer and use it in GitHub Desktop.
From exercism.io
import Test.HUnit (Assertion, (@=?), runTestTT, Test(..), Counts(..))
import System.Exit (ExitCode(..), exitWith)
import qualified LinkedList as L
exitProperly :: IO Counts -> IO ()
exitProperly m = do
counts <- m
exitWith $ if failures counts /= 0 || errors counts /= 0 then ExitFailure 1 else ExitSuccess
testCase :: String -> Assertion -> Test
testCase label assertion = TestLabel label (TestCase assertion)
main :: IO ()
main = exitProperly $ runTestTT $ TestList
[ TestList listTests ]
listTests :: [Test]
listTests =
[ testCase "constructor" $ do
True @=? L.isNil L.nil
1 @=? L.datum one
True @=? L.isNil (L.next one)
2 @=? L.datum two
1 @=? L.datum (L.next two)
True @=? L.isNil (L.next $ L.next two)
, testCase "toList" $ do
([] :: [Int]) @=? L.toList L.nil
[1] @=? L.toList one
[2, 1] @=? L.toList two
, testCase "fromList" $ do
True @=? L.isNil (L.fromList [])
let one_a = L.fromList [1 :: Int]
1 @=? L.datum one_a
True @=? L.isNil (L.next one_a)
let two_a = L.fromList [2, 1 :: Int]
2 @=? L.datum two_a
1 @=? L.datum (L.next two_a)
True @=? L.isNil (L.next $ L.next two_a)
, testCase "reverseList" $ do
True @=? L.isNil (L.reverseLinkedList L.nil)
let one_r = L.reverseLinkedList one
1 @=? L.datum one_r
True @=? L.isNil (L.next one_r)
let two_r = L.reverseLinkedList two
1 @=? L.datum two_r
2 @=? L.datum (L.next two_r)
True @=? L.isNil (L.next $ L.next two_r)
let three_r = L.reverseLinkedList three
1 @=? L.datum three_r
2 @=? L.datum (L.next three_r)
3 @=? L.datum (L.next (L.next three_r))
, testCase "roundtrip" $ do
([] :: [Int]) @=? (L.toList . L.fromList) []
([1] :: [Int]) @=? (L.toList . L.fromList) [1]
([1, 2] :: [Int]) @=? (L.toList . L.fromList) [1, 2]
([1..10] :: [Int]) @=? (L.toList . L.fromList) [1..10]
, testCase "has an unconstrained type variable" $ do
anyTypeMsg @=? (L.toList . L.fromList) anyTypeMsg
([1..10] :: [Integer]) @=? (L.toList . L.fromList) [1..10]
]
where
one = L.new (1 :: Int) L.nil
two = L.new 2 one
three = L.new 3 two
anyTypeMsg = "Should work for any type, not just Int!"
simple-linked-list_test.hs:20:14:
No instance for (Eq a0) arising from a use of ‘L.isNil’
The type variable ‘a0’ is ambiguous
Note: there are several potential instances:
instance Eq Counts -- Defined in ‘Test.HUnit.Base’
instance Eq Test.HUnit.Base.Node -- Defined in ‘Test.HUnit.Base’
instance Eq Test.HUnit.Base.State -- Defined in ‘Test.HUnit.Base’
...plus 38 others
In the second argument of ‘(@=?)’, namely ‘L.isNil L.nil’
In a stmt of a 'do' block: True @=? L.isNil L.nil
In the second argument of ‘($)’, namely
‘do { True @=? L.isNil L.nil;
1 @=? L.datum one;
True @=? L.isNil (L.next one);
2 @=? L.datum two;
.... }’
simple-linked-list_test.hs:31:14:
No instance for (Eq a1) arising from a use of ‘L.isNil’
The type variable ‘a1’ is ambiguous
Note: there are several potential instances:
instance Eq Counts -- Defined in ‘Test.HUnit.Base’
instance Eq Test.HUnit.Base.Node -- Defined in ‘Test.HUnit.Base’
instance Eq Test.HUnit.Base.State -- Defined in ‘Test.HUnit.Base’
...plus 38 others
In the second argument of ‘(@=?)’, namely ‘L.isNil (L.fromList [])’
In a stmt of a 'do' block: True @=? L.isNil (L.fromList [])
In the second argument of ‘($)’, namely
‘do { True @=? L.isNil (L.fromList []);
let one_a = L.fromList ...;
1 @=? L.datum one_a;
True @=? L.isNil (L.next one_a);
.... }’
simple-linked-list_test.hs:40:14:
No instance for (Eq a2) arising from a use of ‘L.isNil’
The type variable ‘a2’ is ambiguous
Note: there are several potential instances:
instance Eq Counts -- Defined in ‘Test.HUnit.Base’
instance Eq Test.HUnit.Base.Node -- Defined in ‘Test.HUnit.Base’
instance Eq Test.HUnit.Base.State -- Defined in ‘Test.HUnit.Base’
...plus 38 others
In the second argument of ‘(@=?)’, namely
‘L.isNil (L.reverseLinkedList L.nil)’
In a stmt of a 'do' block:
True @=? L.isNil (L.reverseLinkedList L.nil)
In the second argument of ‘($)’, namely
‘do { True @=? L.isNil (L.reverseLinkedList L.nil);
let one_r = L.reverseLinkedList one;
1 @=? L.datum one_r;
True @=? L.isNil (L.next one_r);
.... }’
module LinkedList(new, nil, isNil, datum, next, fromList, toList, reverseLinkedList) where
data LinkedList a = Nil | Cons { datum :: a, next :: LinkedList a } deriving Eq
new :: a -> LinkedList a -> LinkedList a
new = Cons
nil = Nil
isNil l = Nil == l
fromList [] = Nil
fromList (x:xs) = Cons x (fromList xs)
toList :: LinkedList a -> [a]
toList Nil = []
toList (Cons d n) = d : toList n
reverseLinkedList = fromList . reverse . toList
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment