packages feed

from 1.0.0.0 → 1.0.0.1

raw patch · 5 files changed

+147/−95 lines, 5 filesdep +fromdep ~bytestringdep ~rawfilepathdep ~unixPVP ok

version bump matches the API change (PVP)

Dependencies added: from

Dependency ranges changed: bytestring, rawfilepath, unix

API changes (from Hackage documentation)

Files

CHANGELOG.md view
@@ -4,16 +4,20 @@  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to the [Haskell Package Versioning Policy](https://pvp.haskell.org/). -## Unreleased+## 1.0.0.1 - 2025-10-24 -(no changes yet)+### Changed +- Split the test code into ordinary test and code generation test. The code generation test will not be run by default (by Hackage or Stackage, for example).+ ## 1.0.0.0 - 2025-10-24  Initial release. -- Added typeclasses `From` and `TryFrom`.-- Added instances of `From` for some fundamental type-mappings in `base`:+### Added++- Typeclasses `From` and `TryFrom`.+- Instances of `From` for some fundamental type-mappings in `base`:     - All types in `Data.Int` and `Data.Word` can be both the source and the destination of the conversion.     - The types `Float` and `Double` can be the destination, but not the source. So `from :: Int32 -> Float` exists, while `from :: Float -> Int32` does not.     - That's it. We begin with minimal instances intentionally. For example, there is no `instance From Int String`. This is because it is tricky (often impossible) to selectively import instances, especially when the module dependency graph is complicated. We'd need to be careful about adding instances.
README.md view
@@ -12,10 +12,15 @@  ## Instances -It is well known that it is difficult to "selectively" import/export typeclass instances. Therefore, we need to be careful about what instances to provide by default.+It is difficult and often impossible to "selectively" import/export typeclass instances. Therefore, we need to be careful about what instances to provide by default. -There are base functions, some of them even in `Prelude`, that basically serve as a less general version of `from`. Examples include `fromIntegral` and `fromEnum`. However, naively defining `instance (Integral a, Num b) => From a b` and `instance (Enum a) => From a Int` will quickly lead us to trouble:+There are base functions, some of them even in `Prelude`, that basically serve as a less general version of `from`. Examples include `fromIntegral` and `fromEnum`. However, naively defining +- `instance (Integral a, Num b) => From a b` and+- `instance (Enum a) => From a Int`++will quickly lead us to trouble:+ ```     • Overlapping instances for From Int16 Int         arising from a use of ‘from’@@ -25,7 +30,7 @@       ... ``` -Therefore, this package does not provide such "contextual" instances. (Of course, you may define them in your application project, if you want.)+Therefore, this package does not provide such "contextual" instances.  Instead, concrete instances are provided. For example, all pairs (excluding self to self) of these integral types are instantiated using `fromIntegral`: 
+ codegen/Main.hs view
@@ -0,0 +1,90 @@+{-# LANGUAGE OverloadedStrings #-}++module Main (main) where++import Control.Exception+import Data.ByteString (ByteString)+import qualified Data.ByteString as B+import Data.ByteString.Builder (Builder)+import qualified Data.ByteString.Builder as B+import RawFilePath+import System.Exit+import System.IO+import System.Posix.Env.ByteString+import System.Posix.Temp.ByteString++srcTypes :: [ByteString]+srcTypes =+  [ "Int"+  , "Integer"+  , "Int8"+  , "Int16"+  , "Int32"+  , "Int64"+  , "Word8"+  , "Word16"+  , "Word32"+  , "Word64"+  ]++dstTypes :: [ByteString]+dstTypes =+  [ "Int"+  , "Integer"+  , "Int8"+  , "Int16"+  , "Int32"+  , "Int64"+  , "Word8"+  , "Word16"+  , "Word32"+  , "Word64"+  , "Float"+  , "Double"+  ]++main :: IO ()+main = do+  args <- getArgs+  let shouldKeepFile = "--keep" `elem` args+  bracket acquire (release shouldKeepFile) $ \(tmpPath, hdl) -> do+    B.putStr $ tmpPath <> "\n"+    B.hPutBuilder hdl $ header <> mconcat instancePart+    hClose hdl+    diffExitCode <-+      runProcess "diff" ["-u", "--color=always", tmpPath, "src/From/Num.hs"]+    case diffExitCode of+      ExitSuccess -> return ()+      _ -> exitWith diffExitCode+ where+  acquire = mkstemps "haskell-from-" ".hs"+  release shouldKeepFile (path, hdl)+    | shouldKeepFile = hClose hdl+    | otherwise = hClose hdl >> removeFile path++  runProcess cmd args = startProcess (proc cmd args) >>= waitForProcess++  instanceLine src dst =+    mconcat ["instance From ", B.byteString src, " ", B.byteString dst, " where\n"]+  instancePart =+    [ mconcat+        [ "\n"+        , "-- | Implementation is 'fromIntegral'\n"+        , instanceLine src dst+        , "  from = fromIntegral\n"+        ]+    | src <- srcTypes+    , dst <- dstTypes+    , src /= dst+    ]++header :: Builder+header =+  "{-# LANGUAGE MultiParamTypeClasses #-}\n\+  \{-# OPTIONS_GHC -Wno-orphans #-}\n\+  \\n\+  \module From.Num () where\n\+  \\n\+  \import Data.Int\n\+  \import Data.Word\n\+  \import From.Classes\n"
from.cabal view
@@ -5,7 +5,7 @@ -- see: https://github.com/sol/hpack  name:           from-version:        1.0.0.0+version:        1.0.0.1 synopsis:       Typeclasses for type conversion mappings description:    This package provides the typeclasses 'From' and 'TryFrom'.                 .@@ -41,6 +41,11 @@   type: git   location: https://codeberg.org/xt/from +flag codegen+  description: Enable code generation test+  manual: True+  default: False+ library   exposed-modules:       From@@ -55,17 +60,34 @@       base >=4.7 && <5   default-language: Haskell2010 -test-suite from-test+test-suite codegen   type: exitcode-stdio-1.0   main-is: Main.hs   other-modules:       Paths_from   hs-source-dirs:+      codegen+  ghc-options: -Wall -Wcompat -Widentities -Wincomplete-record-updates -Wincomplete-uni-patterns -Wmissing-export-lists -Wmissing-home-modules -Wpartial-fields -Wredundant-constraints+  build-depends:+      base >=4.7 && <5+    , bytestring >=0.11.4.0 && <2+    , rawfilepath >=1.0.1 && <2+    , unix >2.7.3 && <3+  default-language: Haskell2010+  if flag(codegen)+    buildable: True+  else+    buildable: False++test-suite test+  type: exitcode-stdio-1.0+  main-is: Main.hs+  other-modules:+      Paths_from+  hs-source-dirs:       test   ghc-options: -Wall -Wcompat -Widentities -Wincomplete-record-updates -Wincomplete-uni-patterns -Wmissing-export-lists -Wmissing-home-modules -Wpartial-fields -Wredundant-constraints   build-depends:       base >=4.7 && <5-    , bytestring-    , rawfilepath-    , unix+    , from   default-language: Haskell2010
test/Main.hs view
@@ -1,90 +1,21 @@-{-# LANGUAGE OverloadedStrings #-}- module Main (main) where -import Control.Exception-import Data.ByteString (ByteString)-import qualified Data.ByteString as B-import Data.ByteString.Builder (Builder)-import qualified Data.ByteString.Builder as B-import RawFilePath+import Data.Int+import Data.Word+import From import System.Exit-import System.IO-import System.Posix.Env.ByteString-import System.Posix.Temp.ByteString -srcTypes :: [ByteString]-srcTypes =-  [ "Int"-  , "Integer"-  , "Int8"-  , "Int16"-  , "Int32"-  , "Int64"-  , "Word8"-  , "Word16"-  , "Word32"-  , "Word64"-  ]--dstTypes :: [ByteString]-dstTypes =-  [ "Int"-  , "Integer"-  , "Int8"-  , "Int16"-  , "Int32"-  , "Int64"-  , "Word8"-  , "Word16"-  , "Word32"-  , "Word64"-  , "Float"-  , "Double"-  ]+assertEq :: (Eq term) => String -> term -> term -> IO ()+assertEq comment leftTerm rightTerm+  | leftTerm == rightTerm = report+  | otherwise = report >> exitFailure+ where+  report = putStrLn comment +-- TODO: More test cases main :: IO () main = do-  args <- getArgs-  let shouldKeepFile = "--keep" `elem` args-  bracket acquire (release shouldKeepFile) $ \(tmpPath, hdl) -> do-    B.putStr $ tmpPath <> "\n"-    B.hPutBuilder hdl $ header <> mconcat instancePart-    hClose hdl-    diffExitCode <--      runProcess "diff" ["-u", "--color=always", tmpPath, "src/From/Num.hs"]-    case diffExitCode of-      ExitSuccess -> return ()-      _ -> exitWith diffExitCode- where-  acquire = mkstemps "haskell-from-" ".hs"-  release shouldKeepFile (path, hdl)-    | shouldKeepFile = hClose hdl-    | otherwise = hClose hdl >> removeFile path--  runProcess cmd args = startProcess (proc cmd args) >>= waitForProcess--  instanceLine src dst =-    mconcat ["instance From ", B.byteString src, " ", B.byteString dst, " where\n"]-  instancePart =-    [ mconcat-        [ "\n"-        , "-- | Implementation is 'fromIntegral'\n"-        , instanceLine src dst-        , "  from = fromIntegral\n"-        ]-    | src <- srcTypes-    , dst <- dstTypes-    , src /= dst-    ]--header :: Builder-header =-  "{-# LANGUAGE MultiParamTypeClasses #-}\n\-  \{-# OPTIONS_GHC -Wno-orphans #-}\n\-  \\n\-  \module From.Num () where\n\-  \\n\-  \import Data.Int\n\-  \import Data.Word\n\-  \import From.Classes\n"+  assertEq+    "round trip from Int8 to Word32"+    (0x11 :: Int8)+    (from (from (0x11 :: Int8) :: Word32))