Advertisement
Guest User

Untitled

a guest
Jun 30th, 2015
183
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.43 KB | None | 0 0
  1. {-# LANGUAGE UndecidableInstances #-}
  2. {-# LANGUAGE TypeFamilies #-}
  3. {-# LANGUAGE GADTs #-}
  4. {-# LANGUAGE KindSignatures #-}
  5. {-# LANGUAGE DataKinds #-}
  6. {-# LANGUAGE TemplateHaskell #-}
  7. {-# LANGUAGE ScopedTypeVariables #-}
  8.  
  9. module Main where
  10.  
  11. import Control.Monad
  12. import Data.Promotion.Prelude hiding (Nat)
  13. import Data.Singletons
  14. import Data.Singletons.Prelude.Ord
  15. import Data.Singletons.TH
  16. import Prelude hiding (length)
  17.  
  18. singletons [d|
  19. data Nat = Zero | Succ Nat deriving (Eq, Ord)
  20. |]
  21.  
  22. sNatToInt :: SNat n -> Int
  23. sNatToInt SZero = 0
  24. sNatToInt (SSucc n) = 1 + sNatToInt n
  25.  
  26. intToNat :: Int -> Nat
  27. intToNat 0 = Zero
  28. intToNat n | n > 0 = Succ (intToNat (n-1))
  29. | otherwise = error "Has to be > 0"
  30.  
  31. data Vector :: Nat -> * -> * where
  32. Nil :: Vector 'Zero a
  33. Cons :: a -> Vector n a -> Vector ('Succ n) a
  34.  
  35. parseInt :: String -> Maybe Int
  36. parseInt str = case reads str of
  37. ((i,_):_) -> Just i
  38. _ -> Nothing
  39.  
  40.  
  41. data Fin :: Nat -> * where
  42. FZero :: Fin n
  43. FSucc :: Fin n -> Fin ('Succ n)
  44.  
  45. intToFin :: forall n . Int -> SNat n -> Maybe (Fin n)
  46. intToFin 0 _ = Just FZero
  47. intToFin n _ | n < 0 = Nothing
  48. intToFin _ SZero = Nothing
  49. intToFin n (SSucc m) = case intToFin (n-1) m of
  50. Nothing -> Nothing
  51. Just f -> Just $ FSucc f
  52.  
  53.  
  54. indexVector :: Fin n -> Vector ('Succ n) a -> a
  55. indexVector FZero (Cons a _) = a
  56. indexVector (FSucc m) (Cons _ vs) = indexVector m vs
  57.  
  58. enumVector :: SNat n -> Vector n Int
  59. enumVector SZero = Nil
  60. enumVector (SSucc n) = Cons (sNatToInt n) (enumVector n)
  61.  
  62. -- -- Actual program of interest:
  63.  
  64. main :: IO ()
  65. main = do
  66. putStrLn "How big should the vector be?"
  67. sizeString <- getLine
  68. case parseInt sizeString of
  69. Nothing ->
  70. putStrLn "Couldn't parse an integer."
  71. Just int ->
  72. case toSing (intToNat int) of
  73. SomeSing length' -> do
  74. let length = SSucc length'
  75. let myVector = enumVector length
  76. forever
  77. (do putStrLn "Enter an index to look at: "
  78. indexString <- getLine
  79. case parseInt indexString of
  80. Nothing -> putStrLn "Couldn't parse an integer."
  81. Just mbIdx ->
  82. case intToFin mbIdx length' of
  83. Nothing -> putStrLn "Couldn't convert to number within bounds."
  84. Just idx ->
  85. do putStrLn "The value is:"
  86. print (indexVector idx myVector))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement