base 4.19.0.0 → 4.19.1.0
raw patch · 14 files changed
+1149/−269 lines, 14 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
Files
- Data/Function.hs +59/−8
- Data/List.hs +12/−5
- Data/Monoid.hs +22/−7
- Data/OldList.hs +331/−86
- Data/Semigroup.hs +86/−5
- Data/Semigroup/Internal.hs +68/−22
- Data/String.hs +20/−2
- GHC/Base.hs +148/−15
- GHC/IO/Handle/Text.hs +16/−4
- GHC/List.hs +329/−107
- System/Posix/Internals.hs +1/−1
- base.cabal +1/−1
- changelog.md +7/−1
- jsbits/base.js +49/−5
Data/Function.hs view
@@ -39,20 +39,44 @@ -- | @'fix' f@ is the least fixed point of the function @f@, -- i.e. the least defined @x@ such that @f x = x@. ----- For example, we can write the factorial function using direct recursion as+-- When @f@ is strict, this means that because, by the definition of strictness,+-- @f ⊥ = ⊥@ and such the least defined fixed point of any strict function is @⊥@. --+-- ==== __Examples__+--+-- We can write the factorial function using direct recursion as+-- -- >>> let fac n = if n <= 1 then 1 else n * fac (n-1) in fac 5 -- 120 -- -- This uses the fact that Haskell’s @let@ introduces recursive bindings. We can -- rewrite this definition using 'fix', ----- >>> fix (\rec n -> if n <= 1 then 1 else n * rec (n-1)) 5--- 120--- -- Instead of making a recursive call, we introduce a dummy parameter @rec@; -- when used within 'fix', this parameter then refers to 'fix'’s argument, hence -- the recursion is reintroduced.+--+-- >>> fix (\rec n -> if n <= 1 then 1 else n * rec (n-1)) 5+-- 120+--+-- Using 'fix', we can implement versions of 'Data.List.repeat' as @'fix' '.' '(:)'@+-- and 'Data.List.cycle' as @'fix' '.' '(++)'@+--+-- >>> take 10 $ fix (0:)+-- [0,0,0,0,0,0,0,0,0,0]+--+-- >>> map (fix (\rec n -> if n < 2 then n else rec (n - 1) + rec (n - 2))) [1..10]+-- [1,1,2,3,5,8,13,21,34,55]+--+-- ==== __Implementation Details__+--+-- The current implementation of 'fix' uses structural sharing+--+-- @'fix' f = let x = f x in x@+--+-- A more straightforward but non-sharing version would look like+--+-- @'fix' f = f ('fix' f)@ fix :: (a -> a) -> a fix f = let x = f x in x @@ -60,12 +84,21 @@ -- unary function @u@ to two arguments @x@ and @y@. From the opposite -- perspective, it transforms two inputs and combines the outputs. ----- @((+) \``on`\` f) x y = f x + f y@+-- @(op \``on`\` f) x y = f x \``op`\` f y@ ----- Typical usage: @'Data.List.sortBy' ('Prelude.compare' \`on\` 'Prelude.fst')@.+-- ==== __Examples__ ----- Algebraic properties:+-- >>> sortBy (compare `on` length) [[0, 1, 2], [0, 1], [], [0]]+-- [[],[0],[0,1],[0,1,2]] --+-- >>> ((+) `on` length) [1, 2, 3] [-1]+-- 4+--+-- >>> ((,) `on` (*2)) 2 3+-- (4,6)+--+-- ==== __Algebraic properties__+-- -- * @(*) \`on\` 'id' = (*) -- (if (*) ∉ {⊥, 'const' ⊥})@ -- -- * @((*) \`on\` f) \`on\` g = (*) \`on\` (f . g)@@@ -118,9 +151,19 @@ -- convenience. Its precedence is one higher than that of the forward -- application operator '$', which allows '&' to be nested in '$'. --+--+-- This is a version of @'flip' 'id'@, where 'id' is specialized from @a -> a@ to @(a -> b) -> (a -> b)@+-- which by the associativity of @(->)@ is @(a -> b) -> a -> b@.+-- flipping this yields @a -> (a -> b) -> b@ which is the type signature of '&'+--+-- ==== __Examples__+-- -- >>> 5 & (+1) & show -- "6" --+-- >>> sqrt $ [1 / n^2 | n <- [1..1000]] & sum & (*6)+-- 3.1406380562059946+-- -- @since 4.8.0.0 (&) :: forall r a (b :: TYPE r). a -> (a -> b) -> b x & f = f x@@ -130,7 +173,15 @@ -- -- It is equivalent to @'flip' ('Data.Bool.bool' 'id')@. ----- Algebraic properties:+-- ==== __Examples__+--+-- >>> map (\x -> applyWhen (odd x) (*2) x) [1..10]+-- [2,2,6,4,10,6,14,8,18,10]+--+-- >>> map (\x -> applyWhen (length x > 6) ((++ "...") . take 3) x) ["Hi!", "This is amazing", "Hope you're doing well today!", ":D"]+-- ["Hi!","Thi...","Hop...",":D"]+--+-- ==== __Algebraic properties__ -- -- * @applyWhen 'True' = 'id'@ --
Data/List.hs view
@@ -227,15 +227,21 @@ -- the elements of the first list occur, in order, in the second. The -- elements do not have to occur consecutively. ----- @'isSubsequenceOf' x y@ is equivalent to @'elem' x ('subsequences' y)@.+-- @'isSubsequenceOf' x y@ is equivalent to @x \`'elem'\` ('subsequences' y)@. --+-- Note: 'isSubsequenceOf' is often used in infix form.+-- -- @since 4.8.0.0 ----- >>> isSubsequenceOf "GHC" "The Glorious Haskell Compiler"+-- ==== __Examples__+--+-- >>> "GHC" `isSubsequenceOf` "The Glorious Haskell Compiler" -- True--- >>> isSubsequenceOf ['a','d'..'z'] ['a'..'z']+--+-- >>> ['a','d'..'z'] `isSubsequenceOf` ['a'..'z'] -- True--- >>> isSubsequenceOf [1..10] [10,9..0]+--+-- >>> [1..10] `isSubsequenceOf` [10,9..0] -- False -- -- For the result to be 'True', the first list must be finite;@@ -243,11 +249,12 @@ -- -- >>> [0,2..10] `isSubsequenceOf` [0..] -- True+-- -- >>> [0..] `isSubsequenceOf` [0,2..10] -- False+-- -- >>> [0,2..] `isSubsequenceOf` [0..] -- * Hangs forever*--- isSubsequenceOf :: (Eq a) => [a] -> [a] -> Bool isSubsequenceOf [] _ = True isSubsequenceOf _ [] = False
Data/Monoid.hs view
@@ -127,14 +127,18 @@ -- @'First' a@ is isomorphic to @'Alt' 'Maybe' a@, but precedes it -- historically. ----- >>> getFirst (First (Just "hello") <> First Nothing <> First (Just "world"))--- Just "hello"--- -- Beware that @Data.Monoid.@'First' is different from -- @Data.Semigroup.@'Data.Semigroup.First'. The former returns the first non-'Nothing', -- so @Data.Monoid.First Nothing <> x = x@. The latter simply returns the first value, -- thus @Data.Semigroup.First Nothing <> x = Data.Semigroup.First Nothing@. --+-- ==== __Examples__+--+-- >>> First (Just "hello") <> First Nothing <> First (Just "world")+-- First {getFirst = Just "hello"}+--+-- >>> First Nothing <> mempty+-- First {getFirst = Nothing} newtype First a = First { getFirst :: Maybe a } deriving ( Eq -- ^ @since 2.01 , Ord -- ^ @since 2.01@@ -162,14 +166,17 @@ -- @'Last' a@ is isomorphic to @'Dual' ('First' a)@, and thus to -- @'Dual' ('Alt' 'Maybe' a)@ ----- >>> getLast (Last (Just "hello") <> Last Nothing <> Last (Just "world"))--- Just "world"------ Beware that @Data.Monoid.@'Last' is different from -- @Data.Semigroup.@'Data.Semigroup.Last'. The former returns the last non-'Nothing', -- so @x <> Data.Monoid.Last Nothing = x@. The latter simply returns the last value, -- thus @x <> Data.Semigroup.Last Nothing = Data.Semigroup.Last Nothing@. --+-- ==== __Examples__+--+-- >>> Last (Just "hello") <> Last Nothing <> Last (Just "world")+-- Last {getLast = Just "world"}+--+-- >>> Last Nothing <> mempty+-- Last {getLast = Nothing} newtype Last a = Last { getLast :: Maybe a } deriving ( Eq -- ^ @since 2.01 , Ord -- ^ @since 2.01@@ -194,6 +201,14 @@ -- | This data type witnesses the lifting of a 'Monoid' into an -- 'Applicative' pointwise.+--+-- ==== __Examples__+--+-- >>> Ap (Just [1, 2, 3]) <> Ap Nothing+-- Ap {getAp = Nothing}+--+-- >>> Ap [Sum 10, Sum 20] <> Ap [Sum 1, Sum 2]+-- Ap {getAp = [Sum {getSum = 11},Sum {getSum = 12},Sum {getSum = 21},Sum {getSum = 22}]} -- -- @since 4.12.0.0 newtype Ap f a = Ap { getAp :: f a }
Data/OldList.hs view
@@ -230,13 +230,9 @@ -- List functions -- | The 'dropWhileEnd' function drops the largest suffix of a list--- in which the given predicate holds for all elements. For example:+-- in which the given predicate holds for all elements. ----- >>> dropWhileEnd isSpace "foo\n"--- "foo"--- >>> dropWhileEnd isSpace "foo bar"--- "foo bar"--- > dropWhileEnd isSpace ("foo\n" ++ undefined) == "foo" ++ undefined+-- ==== __Laziness__ -- -- This function is lazy in spine, but strict in elements, -- which makes it different from 'reverse' '.' 'dropWhile' @p@ '.' 'reverse',@@ -244,6 +240,7 @@ -- -- >>> take 1 (dropWhileEnd (< 0) (1 : undefined)) -- [1]+-- -- >>> take 1 (reverse $ dropWhile (< 0) $ reverse (1 : undefined)) -- *** Exception: Prelude.undefined --@@ -251,9 +248,20 @@ -- -- >>> last (dropWhileEnd (< 0) [undefined, 1]) -- *** Exception: Prelude.undefined+-- -- >>> last (reverse $ dropWhile (< 0) $ reverse [undefined, 1]) -- 1 --+-- ==== __Examples__+--+-- >>> dropWhileEnd isSpace "foo\n"+-- "foo"+--+-- >>> dropWhileEnd isSpace "foo bar"+-- "foo bar"+-- >>> dropWhileEnd (> 10) [1..20]+-- [1,2,3,4,5,6,7,8,9,10]+-- -- @since 4.5.0.0 dropWhileEnd :: (a -> Bool) -> [a] -> [a] dropWhileEnd p = foldr (\x xs -> if p x && null xs then [] else x : xs) []@@ -262,6 +270,8 @@ -- prefix from a list. It returns 'Nothing' if the list did not start with the -- prefix given, or 'Just' the list after the prefix, if it does. --+-- ===== __Examples__+-- -- >>> stripPrefix "foo" "foobar" -- Just "bar" --@@ -284,16 +294,29 @@ -- or 'Nothing' if there is no such element. -- For the result to be 'Nothing', the list must be finite. --+-- ==== __Examples__+-- -- >>> elemIndex 4 [0..] -- Just 4+--+-- >>> elemIndex 'o' "haskell"+-- Nothing+--+-- >>> elemIndex 0 [1..]+-- * hangs forever * elemIndex :: Eq a => a -> [a] -> Maybe Int elemIndex x xs = findIndex (x==) xs -- arity 2 so that we don't get a PAP; #21345 -- | The 'elemIndices' function extends 'elemIndex', by returning the -- indices of all elements equal to the query element, in ascending order. --+-- ==== __Examples__+-- -- >>> elemIndices 'o' "Hello World" -- [4,7]+--+-- >>> elemIndices 1 [1, 2, 3, 1, 2, 3]+-- [0,3] elemIndices :: Eq a => a -> [a] -> [Int] elemIndices x xs = findIndices (x==) xs -- arity 2 so that we don't get a PAP; #21345 @@ -302,11 +325,16 @@ -- there is no such element. -- For the result to be 'Nothing', the list must be finite. --+-- ==== __Examples__+-- -- >>> find (> 4) [1..] -- Just 5 -- -- >>> find (< 0) [1..10] -- Nothing+--+-- >>> find ('a' `elem`) ["john", "marcus", "paul"]+-- Just "marcus" find :: (a -> Bool) -> [a] -> Maybe a find p = listToMaybe . filter p @@ -315,16 +343,32 @@ -- or 'Nothing' if there is no such element. -- For the result to be 'Nothing', the list must be finite. --+-- ==== __Examples__+-- -- >>> findIndex isSpace "Hello World!" -- Just 5+--+-- >>> findIndex odd [0, 2, 4, 6]+-- Nothing+--+-- >>> findIndex even [1..]+-- Just 1+--+-- >>> findIndex odd [0, 2 ..]+-- * hangs forever * findIndex :: (a -> Bool) -> [a] -> Maybe Int findIndex p = listToMaybe . findIndices p -- | The 'findIndices' function extends 'findIndex', by returning the -- indices of all elements satisfying the predicate, in ascending order. --+-- ==== __Examples__+-- -- >>> findIndices (`elem` "aeiou") "Hello World!" -- [1,4,7]+--+-- >>> findIndices (\l -> length l > 3) ["a", "bcde", "fgh", "ijklmnop"]+-- [1,3] findIndices :: (a -> Bool) -> [a] -> [Int] #if defined(USE_REPORT_PRELUDE) findIndices p xs = [ i | (x,i) <- zip xs [0..], p x]@@ -342,8 +386,11 @@ -- | \(\mathcal{O}(\min(m,n))\). The 'isPrefixOf' function takes two lists and -- returns 'True' iff the first list is a prefix of the second. --+-- ==== __Examples__+-- -- >>> "Hello" `isPrefixOf` "Hello World!" -- True+-- -- >>> "Hello" `isPrefixOf` "Wello Horld!" -- False --@@ -352,10 +399,13 @@ -- -- >>> [0..] `isPrefixOf` [1..] -- False+-- -- >>> [0..] `isPrefixOf` [0..99] -- False+-- -- >>> [0..99] `isPrefixOf` [0..] -- True+-- -- >>> [0..] `isPrefixOf` [0..] -- * Hangs forever * --@@ -372,8 +422,11 @@ -- | The 'isSuffixOf' function takes two lists and returns 'True' iff -- the first list is a suffix of the second. --+-- ==== __Examples__+-- -- >>> "ld!" `isSuffixOf` "Hello World!" -- True+-- -- >>> "World" `isSuffixOf` "Hello World!" -- False --@@ -381,6 +434,7 @@ -- -- >>> [0..] `isSuffixOf` [0..99] -- False+-- -- >>> [0..99] `isSuffixOf` [0..] -- * Hangs forever * --@@ -423,8 +477,11 @@ -- iff the first list is contained, wholly and intact, -- anywhere within the second. --+-- ==== __Examples__+-- -- >>> isInfixOf "Haskell" "I really like Haskell." -- True+-- -- >>> isInfixOf "Ial" "I really like Haskell." -- False --@@ -433,11 +490,12 @@ -- -- >>> [20..50] `isInfixOf` [0..] -- True+-- -- >>> [0..] `isInfixOf` [20..50] -- False+-- -- >>> [0..] `isInfixOf` [0..] -- * Hangs forever *--- isInfixOf :: (Eq a) => [a] -> [a] -> Bool isInfixOf needle haystack = any (isPrefixOf needle) (tails haystack) @@ -446,8 +504,6 @@ -- name 'nub' means \`essence\'.) It is a special case of 'nubBy', which allows -- the programmer to supply their own equality test. ----- >>> nub [1,2,3,4,3,2,1,2,4,3,5]--- [1,2,3,4,5] -- -- If there exists @instance Ord a@, it's faster to use `nubOrd` from the `containers` package -- ([link to the latest online documentation](https://hackage.haskell.org/package/containers/docs/Data-Containers-ListUtils.html#v:nubOrd)),@@ -458,17 +514,31 @@ -- 'map' @Data.List.NonEmpty.@'Data.List.NonEmpty.head' . @Data.List.NonEmpty.@'Data.List.NonEmpty.group' . 'sort', -- which takes \(\mathcal{O}(n \log n)\) time, requires @instance Ord a@ and doesn't -- preserve the order.- --+-- ==== __Examples__+--+-- >>> nub [1,2,3,4,3,2,1,2,4,3,5]+-- [1,2,3,4,5]+--+-- >>> nub "hello, world!"+-- "helo, wrd!" nub :: (Eq a) => [a] -> [a] nub = nubBy (==) -- | The 'nubBy' function behaves just like 'nub', except it uses a--- user-supplied equality predicate instead of the overloaded '=='+-- user-supplied equality predicate instead of the overloaded '(==)' -- function. --+-- ==== __Examples__+-- -- >>> nubBy (\x y -> mod x 3 == mod y 3) [1,2,4,5,6] -- [1,2,6]+--+-- >>> nubBy (/=) [2, 7, 1, 8, 2, 8, 1, 8, 2, 8]+-- [2,2,2]+--+-- >>> nubBy (>) [1, 2, 3, 2, 1, 5, 4, 5, 3, 2]+-- [1,2,3,5,5] nubBy :: (a -> a -> Bool) -> [a] -> [a] #if defined(USE_REPORT_PRELUDE) nubBy eq [] = []@@ -496,21 +566,31 @@ -- | \(\mathcal{O}(n)\). 'delete' @x@ removes the first occurrence of @x@ from--- its list argument. For example,+-- its list argument. --+-- It is a special case of 'deleteBy', which allows the programmer to+-- supply their own equality test.+--+-- ==== __Examples__+-- -- >>> delete 'a' "banana" -- "bnana" ----- It is a special case of 'deleteBy', which allows the programmer to--- supply their own equality test.+-- >>> delete "not" ["haskell", "is", "not", "awesome"]+-- ["haskell","is","awesome"] delete :: (Eq a) => a -> [a] -> [a] delete = deleteBy (==) -- | \(\mathcal{O}(n)\). The 'deleteBy' function behaves like 'delete', but -- takes a user-supplied equality predicate. --+-- ==== __Examples__+-- -- >>> deleteBy (<=) 4 [1..10] -- [1,2,3,5,6,7,8,9,10]+--+-- >>> deleteBy (/=) 5 [5, 5, 4, 3, 5, 2]+-- [5,5,3,5,2] deleteBy :: (a -> a -> Bool) -> a -> [a] -> [a] deleteBy _ _ [] = [] deleteBy eq x (y:ys) = if x `eq` y then ys else y : deleteBy eq x ys@@ -520,27 +600,30 @@ -- @ys@ in turn (if any) has been removed from @xs@. Thus -- @(xs ++ ys) \\\\ xs == ys@. ----- >>> "Hello World!" \\ "ell W"--- "Hoorld!"--- -- It is a special case of 'deleteFirstsBy', which allows the programmer -- to supply their own equality test. --+-- ==== __Examples__+--+-- >>> "Hello World!" \\ "ell W"+-- "Hoorld!"+-- -- The second list must be finite, but the first may be infinite. -- -- >>> take 5 ([0..] \\ [2..4]) -- [0,1,5,6,7]+-- -- >>> take 5 ([0..] \\ [2..]) -- * Hangs forever *--- (\\) :: (Eq a) => [a] -> [a] -> [a] (\\) = foldl (flip delete) -- | The 'union' function returns the list union of the two lists. -- It is a special case of 'unionBy', which allows the programmer to supply -- their own equality test.--- For example, --+-- ==== __Examples__+-- -- >>> "dog" `union` "cow" -- "dogcw" --@@ -548,7 +631,7 @@ -- will be used. If the second list contains equal elements, only the first one -- will be retained: ----- >>> import Data.Semigroup+-- >>> import Data.Semigroup(Arg(..)) -- >>> union [Arg () "dog"] [Arg () "cow"] -- [Arg () "dog"] -- >>> union [] [Arg () "dog", Arg () "cow"]@@ -564,20 +647,31 @@ -- -- 'union' is productive even if both arguments are infinite. --+-- >>> [0, 2 ..] `union` [1, 3 ..]+-- [0,2,4,6,8,10,12.. union :: (Eq a) => [a] -> [a] -> [a] union = unionBy (==) -- | The 'unionBy' function is the non-overloaded version of 'union'. -- Both arguments may be infinite. --+-- ==== __Examples__+--+-- >>> unionBy (>) [3, 4, 5] [1, 2, 3, 4, 5, 6]+-- [3,4,5,4,5,6]+--+-- >>> import Data.Semigroup (Arg(..))+-- >>> unionBy (/=) [Arg () "Saul"] [Arg () "Kim"]+-- [Arg () "Saul", Arg () "Kim"] unionBy :: (a -> a -> Bool) -> [a] -> [a] -> [a] unionBy eq xs ys = xs ++ foldl (flip (deleteBy eq)) (nubBy eq ys) xs -- | The 'intersect' function takes the list intersection of two lists. -- It is a special case of 'intersectBy', which allows the programmer to -- supply their own equality test.--- For example, --+-- ===== __Examples__+-- -- >>> [1,2,3,4] `intersect` [2,4,6,8] -- [2,4] --@@ -621,19 +715,25 @@ intersectBy eq xs ys = [x | x <- xs, any (eq x) ys] -- | \(\mathcal{O}(n)\). The 'intersperse' function takes an element and a list--- and \`intersperses\' that element between the elements of the list. For--- example,+-- and \`intersperses\' that element between the elements of the list. ----- >>> intersperse ',' "abcde"--- "a,b,c,d,e"+-- ==== __Laziness__ ----- 'intersperse' has the following laziness properties:+-- 'intersperse' has the following properties -- -- >>> take 1 (intersperse undefined ('a' : undefined)) -- "a"+-- -- >>> take 2 (intersperse ',' ('a' : undefined)) -- "a*** Exception: Prelude.undefined --+-- ==== __Examples__+--+-- >>> intersperse ',' "abcde"+-- "a,b,c,d,e"+--+-- >>> intersperse 1 [3, 4, 5]+-- [3,1,4,1,5] intersperse :: a -> [a] -> [a] intersperse _ [] = [] intersperse sep (x:xs) = x : prependToAll sep xs@@ -651,22 +751,40 @@ -- It inserts the list @xs@ in between the lists in @xss@ and concatenates the -- result. ----- >>> intercalate ", " ["Lorem", "ipsum", "dolor"]--- "Lorem, ipsum, dolor"+-- ==== __Laziness__ ----- 'intercalate' has the following laziness properties:+-- 'intercalate' has the following properties: -- -- >>> take 5 (intercalate undefined ("Lorem" : undefined)) -- "Lorem"+-- -- >>> take 6 (intercalate ", " ("Lorem" : undefined)) -- "Lorem*** Exception: Prelude.undefined --+-- ==== __Examples__+--+-- >>> intercalate ", " ["Lorem", "ipsum", "dolor"]+-- "Lorem, ipsum, dolor"+--+-- >>> intercalate [0, 1] [[2, 3], [4, 5, 6], []]+-- [2,3,0,1,4,5,6,0,1]+--+-- >>> intercalate [1, 2, 3] [[], []]+-- [1,2,3] intercalate :: [a] -> [[a]] -> [a] intercalate xs xss = concat (intersperse xs xss) -- | The 'transpose' function transposes the rows and columns of its argument.--- For example, --+-- ==== __Laziness__+--+-- 'transpose' is lazy in its elements+--+-- >>> take 1 (transpose ['a' : undefined, 'b' : undefined])+-- ["ab"]+--+-- ==== __Examples__+-- -- >>> transpose [[1,2,3],[4,5,6]] -- [[1,4],[2,5],[3,6]] --@@ -679,12 +797,6 @@ -- -- >>> transpose (repeat []) -- * Hangs forever *------ 'transpose' is lazy:------ >>> take 1 (transpose ['a' : undefined, 'b' : undefined])--- ["ab"]--- transpose :: [[a]] -> [[a]] transpose [] = [] transpose ([] : xss) = transpose xss@@ -741,8 +853,16 @@ -- -- > partition p xs == (filter p xs, filter (not . p) xs) --+-- ==== __Examples__+-- -- >>> partition (`elem` "aeiou") "Hello World!" -- ("eoo","Hll Wrld!")+--+-- >>> partition even [1..10]+-- ([2,4,6,8,10],[1,3,5,7,9])+--+-- >>> partition (< 5) [1..10]+-- ([1,2,3,4],[5,6,7,8,9,10]) partition :: (a -> Bool) -> [a] -> ([a],[a]) {-# INLINE partition #-} partition p xs = foldr (select p) ([],[]) xs@@ -812,12 +932,25 @@ -- call, the result will also be sorted. It is a special case of 'insertBy', -- which allows the programmer to supply their own comparison function. ----- >>> insert 4 [1,2,3,5,6,7]+-- ==== __Examples__+--+-- >>> insert (-1) [1, 2, 3]+-- [-1,1,2,3]+--+-- >>> insert 'd' "abcefg"+-- "abcdefg"+--+-- >>> insert 4 [1, 2, 3, 5, 6, 7] -- [1,2,3,4,5,6,7] insert :: Ord a => a -> [a] -> [a] insert e ls = insertBy (compare) e ls -- | \(\mathcal{O}(n)\). The non-overloaded version of 'insert'.+--+-- ==== __Examples__+--+-- >>> insertBy (\x y -> compare (length x) (length y)) [1, 2] [[1], [1, 2, 3], [1, 2, 3, 4]]+-- [[1],[1,2],[1,2,3],[1,2,3,4]] insertBy :: (a -> a -> Ordering) -> a -> [a] -> [a] insertBy _ x [] = [x] insertBy cmp x ys@(y:ys')@@ -830,10 +963,15 @@ -- and returns the greatest element of the list by the comparison function. -- The list must be finite and non-empty. --+-- ==== __Examples__+-- -- We can use this to find the longest entry of a list: -- -- >>> maximumBy (\x y -> compare (length x) (length y)) ["Hello", "World", "!", "Longest", "bar"] -- "Longest"+--+-- >>> minimumBy (\(a, b) (c, d) -> compare (abs (a - b)) (abs (c - d))) [(10, 15), (1, 2), (3, 5)]+-- (10, 15) maximumBy :: (a -> a -> Ordering) -> [a] -> a maximumBy _ [] = errorWithoutStackTrace "List.maximumBy: empty list" maximumBy cmp xs = foldl1 maxBy xs@@ -847,10 +985,15 @@ -- and returns the least element of the list by the comparison function. -- The list must be finite and non-empty. --+-- ==== __Examples__+-- -- We can use this to find the shortest entry of a list: -- -- >>> minimumBy (\x y -> compare (length x) (length y)) ["Hello", "World", "!", "Longest", "bar"] -- "!"+--+-- >>> minimumBy (\(a, b) (c, d) -> compare (abs (a - b)) (abs (c - d))) [(10, 15), (1, 2), (3, 5)]+-- (1, 2) minimumBy :: (a -> a -> Ordering) -> [a] -> a minimumBy _ [] = errorWithoutStackTrace "List.minimumBy: empty list" minimumBy cmp xs = foldl1 minBy xs@@ -864,6 +1007,8 @@ -- type which is an instance of 'Num'. It is, however, less efficient than -- 'length'. --+-- ==== __Examples__+-- -- >>> genericLength [1, 2, 3] :: Int -- 3 -- >>> genericLength [1, 2, 3] :: Float@@ -1199,18 +1344,24 @@ -- returns the first list with the first occurrence of each element of -- the second list removed. This is the non-overloaded version of '(\\)'. --+-- > (\\) == deleteFirstsBy (==)+-- -- The second list must be finite, but the first may be infinite. --+-- ==== __Examples__+--+-- >>> deleteFirstsBy (>) [1..10] [3, 4, 5]+-- [4,5,6,7,8,9,10]+--+-- >>> deleteFirstsBy (/=) [1..10] [1, 3, 5]+-- [4,5,6,7,8,9,10] deleteFirstsBy :: (a -> a -> Bool) -> [a] -> [a] -> [a] deleteFirstsBy eq = foldl (flip (deleteBy eq)) -- | The 'group' function takes a list and returns a list of lists such -- that the concatenation of the result is equal to the argument. Moreover, -- each sublist in the result is non-empty and all elements are equal--- to the first one. For example,------ >>> group "Mississippi"--- ["M","i","ss","i","ss","i","pp","i"]+-- to the first one. -- -- 'group' is a special case of 'groupBy', which allows the programmer to supply -- their own equality test.@@ -1218,6 +1369,13 @@ -- It's often preferable to use @Data.List.NonEmpty.@'Data.List.NonEmpty.group', -- which provides type-level guarantees of non-emptiness of inner lists. --+-- ==== __Examples__+--+-- >>> group "Mississippi"+-- ["M","i","ss","i","ss","i","pp","i"]+--+-- >>> group [1, 1, 1, 2, 2, 3, 4, 5, 5]+-- [[1,1,1],[2,2],[3],[4],[5,5]] group :: Eq a => [a] -> [[a]] group = groupBy (==) @@ -1233,26 +1391,47 @@ -- It's often preferable to use @Data.List.NonEmpty.@'Data.List.NonEmpty.groupBy', -- which provides type-level guarantees of non-emptiness of inner lists. --+-- ==== __Examples__+--+-- >>> groupBy (/=) [1, 1, 1, 2, 3, 1, 4, 4, 5]+-- [[1],[1],[1,2,3],[1,4,4,5]]+--+-- >>> groupBy (>) [1, 3, 5, 1, 4, 2, 6, 5, 4]+-- [[1],[3],[5,1,4,2],[6,5,4]]+--+-- >>> groupBy (const not) [True, False, True, False, False, False, True]+-- [[True,False],[True,False,False,False],[True]] groupBy :: (a -> a -> Bool) -> [a] -> [[a]] groupBy _ [] = [] groupBy eq (x:xs) = (x:ys) : groupBy eq zs where (ys,zs) = span (eq x) xs -- | The 'inits' function returns all initial segments of the argument,--- shortest first. For example,+-- shortest first. ----- >>> inits "abc"--- ["","a","ab","abc"]+-- 'inits' is semantically equivalent to @'map' 'reverse' . 'scanl' ('flip' (:)) []@,+-- but under the hood uses a queue to amortize costs of 'reverse'. --+-- ==== __Laziness__+-- -- Note that 'inits' has the following strictness property: -- @inits (xs ++ _|_) = inits xs ++ _|_@ -- -- In particular, -- @inits _|_ = [] : _|_@ ----- 'inits' is semantically equivalent to @'map' 'reverse' . 'scanl' ('flip' (:)) []@,--- but under the hood uses a queue to amortize costs of 'reverse'.+-- ==== __Examples__ --+-- >>> inits "abc"+-- ["","a","ab","abc"]+--+-- >>> inits []+-- [[]]+--+-- inits is productive on infinite lists:+--+-- >>> take 5 $ inits [1..]+-- [[],[1],[1,2],[1,2,3],[1,2,3,4]] inits :: [a] -> [[a]] inits = map toListSB . scanl' snocSB emptySB {-# NOINLINE inits #-}@@ -1262,13 +1441,29 @@ -- loss of sharing if allowed to fuse with a producer. -- | \(\mathcal{O}(n)\). The 'tails' function returns all final segments of the--- argument, longest first. For example,+-- argument, longest first. ----- >>> tails "abc"--- ["abc","bc","c",""]+-- ==== __Laziness__ -- -- Note that 'tails' has the following strictness property: -- @tails _|_ = _|_ : _|_@+--+-- >>> tails undefined+-- [*** Exception: Prelude.undefined+--+-- >>> drop 1 (tails [undefined, 1, 2])+-- [[1, 2], [2], []]+--+-- ==== __Examples__+--+-- >>> tails "abc"+-- ["abc","bc","c",""]+--+-- >>> tails [1, 2, 3]+-- [[1,2,3],[2,3],[3],[]]+--+-- >>> tails []+-- [[]] tails :: [a] -> [[a]] {-# INLINABLE tails #-} tails lst = build (\c n ->@@ -1279,13 +1474,7 @@ -- | The 'subsequences' function returns the list of all subsequences of the argument. ----- >>> subsequences "abc"--- ["","a","b","ab","c","ac","bc","abc"]------ This function is productive on infinite inputs:------ >>> take 8 $ subsequences ['a'..]--- ["","a","b","ab","c","ac","bc","abc"]+-- ==== __Laziness__ -- -- 'subsequences' does not look ahead unless it must: --@@ -1294,6 +1483,15 @@ -- >>> take 2 (subsequences ('a' : undefined)) -- ["","a"] --+-- ==== __Examples__+--+-- >>> subsequences "abc"+-- ["","a","b","ab","c","ac","bc","abc"]+--+-- This function is productive on infinite inputs:+--+-- >>> take 8 $ subsequences ['a'..]+-- ["","a","b","ab","c","ac","bc","abc"] subsequences :: [a] -> [[a]] subsequences xs = [] : nonEmptySubsequences xs @@ -1310,23 +1508,32 @@ -- | The 'permutations' function returns the list of all permutations of the argument. ----- >>> permutations "abc"--- ["abc","bac","cba","bca","cab","acb"]+-- Note that the order of permutations is not lexicographic.+-- It satisfies the following property: --+-- > map (take n) (take (product [1..n]) (permutations ([1..n] ++ undefined))) == permutations [1..n]+--+-- ==== __Laziness__+-- -- The 'permutations' function is maximally lazy: -- for each @n@, the value of @'permutations' xs@ starts with those permutations -- that permute @'take' n xs@ and keep @'drop' n xs@. ----- This function is productive on infinite inputs:+-- ==== __Examples__ ----- >>> take 6 $ map (take 3) $ permutations ['a'..]+-- >>> permutations "abc" -- ["abc","bac","cba","bca","cab","acb"] ----- Note that the order of permutations is not lexicographic.--- It satisfies the following property:+-- >>> permutations [1, 2]+-- [[1,2],[2,1]] ----- > map (take n) (take (product [1..n]) (permutations ([1..n] ++ undefined))) == permutations [1..n]+-- >>> permutations []+-- [[]] --+-- This function is productive on infinite inputs:+--+-- >>> take 6 $ map (take 3) $ permutations ['a'..]+-- ["abc","bac","cba","bca","cab","acb"] permutations :: [a] -> [[a]] -- See https://stackoverflow.com/questions/24484348/what-does-this-list-permutations-implementation-in-haskell-exactly-do/24564307#24564307 -- for the analysis of this rather cryptic implementation.@@ -1384,24 +1591,33 @@ -- Elements are arranged from lowest to highest, keeping duplicates in -- the order they appeared in the input. --+-- The argument must be finite.+--+-- ==== __Examples__+-- -- >>> sort [1,6,4,3,2,5] -- [1,2,3,4,5,6] ----- The argument must be finite.+-- >>> sort "haskell"+-- "aehklls" --+-- >>> import Data.Semigroup(Arg(..))+-- >>> sort [Arg ":)" 0, Arg ":D" 0, Arg ":)" 1, Arg ":3" 0, Arg ":D" 1]+-- [Arg ":)" 0,Arg ":)" 1,Arg ":3" 0,Arg ":D" 0,Arg ":D" 1] sort :: (Ord a) => [a] -> [a] -- | The 'sortBy' function is the non-overloaded version of 'sort'. -- The argument must be finite. ----- >>> sortBy (\(a,_) (b,_) -> compare a b) [(2, "world"), (4, "!"), (1, "Hello")]--- [(1,"Hello"),(2,"world"),(4,"!")]--- -- The supplied comparison relation is supposed to be reflexive and antisymmetric, -- otherwise, e. g., for @\_ _ -> GT@, the ordered list simply does not exist. -- The relation is also expected to be transitive: if it is not then 'sortBy' -- might fail to find an ordered permutation, even if it exists. --+-- ==== __Examples__+--+-- >>> sortBy (\(a,_) (b,_) -> compare a b) [(2, "world"), (4, "!"), (1, "Hello")]+-- [(1,"Hello"),(2,"world"),(4,"!")] sortBy :: (a -> a -> Ordering) -> [a] -> [a] #if defined(USE_REPORT_PRELUDE)@@ -1567,10 +1783,15 @@ -- Elements are arranged from lowest to highest, keeping duplicates in -- the order they appeared in the input. --+-- The argument must be finite.+--+-- ==== __Examples__+-- -- >>> sortOn fst [(2, "world"), (4, "!"), (1, "Hello")] -- [(1,"Hello"),(2,"world"),(4,"!")] ----- The argument must be finite.+-- >>> sortOn length ["jim", "creed", "pam", "michael", "dwight", "kevin"]+-- ["jim","pam","creed","kevin","dwight","michael"] -- -- @since 4.8.0.0 sortOn :: Ord b => (a -> b) -> [a] -> [a]@@ -1579,9 +1800,17 @@ -- | Construct a list from a single element. --+-- ==== __Examples__+-- -- >>> singleton True -- [True] --+-- >>> singleton [1, 2, 3]+--[[1,2,3]]+--+-- >>> singleton 'c'+-- "c"+-- -- @since 4.15.0.0 -- singleton :: a -> [a]@@ -1605,16 +1834,19 @@ -- > f' (f x y) = Just (x,y) -- > f' z = Nothing ----- A simple use of unfoldr: ----- >>> unfoldr (\b -> if b == 0 then Nothing else Just (b, b-1)) 10--- [10,9,8,7,6,5,4,3,2,1]------ Laziness:+-- ==== __Laziness__ -- -- >>> take 1 (unfoldr (\x -> Just (x, undefined)) 'a') -- "a" --+-- ==== __Examples__+--+-- >>> unfoldr (\b -> if b == 0 then Nothing else Just (b, b-1)) 10+-- [10,9,8,7,6,5,4,3,2,1]+--+-- >>> take 10 $ unfoldr (\(x, y) -> Just (x, (y, x + y))) (0, 1)+-- [0,1,1,2,3,5,8,13,21,54] -- Note [INLINE unfoldr] -- ~~~~~~~~~~~~~~~~~~~~~@@ -1656,30 +1888,35 @@ -- @\\n@ characters. The @\\n@ terminator is optional in a final non-empty -- line of the argument string. ----- For example:+-- When the argument string is empty, or ends in a @\\n@ character, it can be+-- recovered by passing the result of 'lines' to the 'unlines' function.+-- Otherwise, 'unlines' appends the missing terminating @\\n@. This makes+-- @unlines . lines@ /idempotent/: --+-- > (unlines . lines) . (unlines . lines) = (unlines . lines)+--+-- ==== __Examples__+-- -- >>> lines "" -- empty input contains no lines -- []+-- -- >>> lines "\n" -- single empty line -- [""]+-- -- >>> lines "one" -- single unterminated line -- ["one"]+-- -- >>> lines "one\n" -- single non-empty line -- ["one"]+-- -- >>> lines "one\n\n" -- second line is empty -- ["one",""]+-- -- >>> lines "one\ntwo" -- second line is unterminated -- ["one","two"]+-- -- >>> lines "one\ntwo\n" -- two non-empty lines -- ["one","two"]------ When the argument string is empty, or ends in a @\\n@ character, it can be--- recovered by passing the result of 'lines' to the 'unlines' function.--- Otherwise, 'unlines' appends the missing terminating @\\n@. This makes--- @unlines . lines@ /idempotent/:------ > (unlines . lines) . (unlines . lines) = (unlines . lines)--- lines :: String -> [String] lines "" = [] -- Somehow GHC doesn't detect the selector thunks in the below code,@@ -1696,6 +1933,8 @@ -- | Appends a @\\n@ character to each input string, then concatenates the -- results. Equivalent to @'foldMap' (\s -> s '++' "\\n")@. --+-- ==== __Examples__+-- -- >>> unlines ["Hello", "World", "!"] -- "Hello\nWorld\n!\n" --@@ -1717,11 +1956,13 @@ -- by white space (as defined by 'isSpace'). This function trims any white spaces -- at the beginning and at the end. --+-- ==== __Examples__+-- -- >>> words "Lorem ipsum\ndolor" -- ["Lorem","ipsum","dolor"]+-- -- >>> words " foo bar " -- ["foo","bar"]--- words :: String -> [String] {-# NOINLINE [1] words #-} words s = case dropWhile {-partain:Char.-}isSpace s of@@ -1745,9 +1986,6 @@ -- | 'unwords' joins words with separating spaces (U+0020 SPACE). ----- >>> unwords ["Lorem", "ipsum", "dolor"]--- "Lorem ipsum dolor"--- -- 'unwords' is neither left nor right inverse of 'words': -- -- >>> words (unwords [" "])@@ -1755,6 +1993,13 @@ -- >>> unwords (words "foo\nbar") -- "foo bar" --+-- ==== __Examples__+--+-- >>> unwords ["Lorem", "ipsum", "dolor"]+-- "Lorem ipsum dolor"+--+-- >>> unwords ["foo", "bar", "", "baz"]+-- "foo bar baz" unwords :: [String] -> String #if defined(USE_REPORT_PRELUDE) unwords [] = ""
Data/Semigroup.hs view
@@ -26,6 +26,7 @@ -- -- The 'Min' 'Semigroup' instance for 'Int' is defined to always pick the smaller -- number:+-- -- >>> Min 1 <> Min 2 <> Min 3 <> Min 4 :: Min Int -- Min {getMin = 1} --@@ -48,6 +49,7 @@ -- -- >>> sconcat (1 :| [2, 3, 4]) :: Min Int -- Min {getMin = 1}+-- -- >>> sconcat (1 :| [2, 3, 4]) :: Max Int -- Max {getMax = 4} --@@ -120,28 +122,56 @@ -- | A generalization of 'Data.List.cycle' to an arbitrary 'Semigroup'. -- May fail to terminate for some values in some semigroups.+--+-- ==== __Examples__+--+-- >>> take 10 $ cycle1 [1, 2, 3]+-- [1,2,3,1,2,3,1,2,3,1]+--+-- >>> cycle1 (Right 1)+-- Right 1+--+-- >>> cycle1 (Left 1)+-- * hangs forever * cycle1 :: Semigroup m => m -> m cycle1 xs = xs' where xs' = xs <> xs' -- | This lets you use a difference list of a 'Semigroup' as a 'Monoid'. ----- === __Example:__--- >>> let hello = diff "Hello, "+-- ==== __Examples__+--+-- > let hello = diff "Hello, "+-- -- >>> appEndo hello "World!" -- "Hello, World!"+-- -- >>> appEndo (hello <> mempty) "World!" -- "Hello, World!"+-- -- >>> appEndo (mempty <> hello) "World!" -- "Hello, World!"--- >>> let world = diff "World"--- >>> let excl = diff "!"+--+-- > let world = diff "World"+-- > let excl = diff "!"+-- -- >>> appEndo (hello <> (world <> excl)) mempty -- "Hello, World!"+-- -- >>> appEndo ((hello <> world) <> excl) mempty -- "Hello, World!" diff :: Semigroup m => m -> Endo m diff = Endo . (<>) +-- | The 'Min' 'Monoid' and 'Semigroup' always choose the smaller element as+-- by the 'Ord' instance and 'min' of the contained type.+--+-- ==== __Examples__+--+-- >>> Min 42 <> Min 3+-- Min 3+--+-- >>> sconcat $ Min 1 :| [ Min n | n <- [2 .. 100]]+-- Min {getMin = 1} newtype Min a = Min { getMin :: a } deriving ( Bounded -- ^ @since 4.9.0.0 , Eq -- ^ @since 4.9.0.0@@ -217,6 +247,16 @@ signum (Min a) = Min (signum a) fromInteger = Min . fromInteger +-- | The 'Max' 'Monoid' and 'Semigroup' always choose the bigger element as+-- by the 'Ord' instance and 'max' of the contained type.+--+-- ==== __Examples__+--+-- >>> Max 42 <> Max 3+-- Max 42+--+-- >>> sconcat $ Max 1 :| [ Max n | n <- [2 .. 100]]+-- Max {getMax = 100} newtype Max a = Max { getMax :: a } deriving ( Bounded -- ^ @since 4.9.0.0 , Eq -- ^ @since 4.9.0.0@@ -294,8 +334,16 @@ -- | 'Arg' isn't itself a 'Semigroup' in its own right, but it can be -- placed inside 'Min' and 'Max' to compute an arg min or arg max. --+-- ==== __Examples__+-- -- >>> minimum [ Arg (x * x) x | x <- [-10 .. 10] ] -- Arg 0 0+--+-- >>> maximum [ Arg (-0.2*x^2 + 1.5*x + 1) x | x <- [-10 .. 10] ]+-- Arg 3.8 4.0+--+-- >>> minimum [ Arg (-0.2*x^2 + 1.5*x + 1) x | x <- [-10 .. 10] ]+-- Arg (-34.0) (-10.0) data Arg a b = Arg a -- ^ The argument used for comparisons in 'Eq' and 'Ord'.@@ -310,13 +358,23 @@ ) -- |+-- ==== __Examples__+-- -- >>> Min (Arg 0 ()) <> Min (Arg 1 ()) -- Min {getMin = Arg 0 ()}+--+-- >>> minimum [ Arg (length name) name | name <- ["violencia", "lea", "pixie"]]+-- Arg 3 "lea" type ArgMin a b = Min (Arg a b) -- |+-- ==== __Examples__+-- -- >>> Max (Arg 0 ()) <> Max (Arg 1 ()) -- Max {getMax = Arg 1 ()}+--+-- >>> maximum [ Arg (length name) name | name <- ["violencia", "lea", "pixie"]]+-- Arg 9 "violencia" type ArgMax a b = Max (Arg a b) -- | @since 4.9.0.0@@ -364,6 +422,13 @@ -- The latter returns the first non-'Nothing', -- thus @Data.Monoid.First Nothing <> x = x@. --+-- ==== __Examples__+--+-- >>> First 0 <> First 10+-- First 0+--+-- >>> sconcat $ First 1 :| [ First n | n <- [2 ..] ]+-- First 1 newtype First a = First { getFirst :: a } deriving ( Bounded -- ^ @since 4.9.0.0 , Eq -- ^ @since 4.9.0.0@@ -427,6 +492,13 @@ -- The latter returns the last non-'Nothing', -- thus @x <> Data.Monoid.Last Nothing = x@. --+-- ==== __Examples__+--+-- >>> Last 0 <> Last 10+-- Last {getLast = 10}+--+-- >>> sconcat $ Last 1 :| [ Last n | n <- [2..]]+-- Last {getLast = * hangs forever * newtype Last a = Last { getLast :: a } deriving ( Bounded -- ^ @since 4.9.0.0 , Eq -- ^ @since 4.9.0.0@@ -526,7 +598,7 @@ -- -- > mtimesDefault n a = a <> a <> ... <> a -- using <> (n-1) times ----- In many cases, `stimes 0 a` for a `Monoid` will produce `mempty`.+-- In many cases, @'stimes' 0 a@ for a `Monoid` will produce `mempty`. -- However, there are situations when it cannot do so. In particular, -- the following situation is fairly common: --@@ -535,6 +607,7 @@ -- -- class Constraint1 a -- class Constraint1 a => Constraint2 a+-- @ -- -- @ -- instance Constraint1 a => 'Semigroup' (T a)@@ -548,6 +621,14 @@ -- 'Semigroup' instances, @mtimesDefault@ should be used when the -- multiplier might be zero. It is implemented using 'stimes' when -- the multiplier is nonzero and 'mempty' when it is zero.+--+-- ==== __Examples__+--+-- >>> mtimesDefault 0 "bark"+-- []+--+-- >>> mtimesDefault 3 "meow"+-- "meowmeowmeow" mtimesDefault :: (Integral b, Monoid a) => b -> a -> a mtimesDefault n x | n == 0 = mempty
Data/Semigroup/Internal.hs view
@@ -40,7 +40,7 @@ -- | This is a valid definition of 'stimes' for an idempotent 'Monoid'. ----- When @mappend x x = x@, this definition should be preferred, because it+-- When @x <> x = x@, this definition should be preferred, because it -- works in \(\mathcal{O}(1)\) rather than \(\mathcal{O}(\log n)\) stimesIdempotentMonoid :: (Integral b, Monoid a) => b -> a -> a stimesIdempotentMonoid n x = case compare n 0 of@@ -104,10 +104,17 @@ rep 0 = [] rep i = x ++ rep (i - 1) --- | The dual of a 'Monoid', obtained by swapping the arguments of 'mappend'.+-- | The dual of a 'Monoid', obtained by swapping the arguments of '(<>)'. ----- >>> getDual (mappend (Dual "Hello") (Dual "World"))--- "WorldHello"+-- > Dual a <> Dual b == Dual (b <> a)+--+-- ==== __Examples__+--+-- >>> Dual "Hello" <> Dual "World"+-- Dual {getDual = "WorldHello"}+--+-- >>> Dual (Dual "Hello") <> Dual (Dual "World")+-- Dual {getDual = Dual {getDual = "HelloWorld"}} newtype Dual a = Dual { getDual :: a } deriving ( Eq -- ^ @since 2.01 , Ord -- ^ @since 2.01@@ -142,9 +149,17 @@ -- | The monoid of endomorphisms under composition. --+-- > Endo f <> Endo g == Endo (f . g)+--+-- ==== __Examples__+-- -- >>> let computation = Endo ("Hello, " ++) <> Endo (++ "!") -- >>> appEndo computation "Haskell" -- "Hello, Haskell!"+--+-- >>> let computation = Endo (*3) <> Endo (+1)+-- >>> appEndo computation 1+-- 6 newtype Endo a = Endo { appEndo :: a -> a } deriving ( Generic -- ^ @since 4.7.0.0 )@@ -158,13 +173,20 @@ instance Monoid (Endo a) where mempty = Endo id --- | Boolean monoid under conjunction ('&&').+-- | Boolean monoid under conjunction '(&&)'. ----- >>> getAll (All True <> mempty <> All False)--- False+-- > All x <> All y = All (x && y) ----- >>> getAll (mconcat (map (\x -> All (even x)) [2,4,6,7,8]))--- False+-- ==== __Examples__+--+-- >>> All True <> mempty <> All False)+-- All {getAll = False}+--+-- >>> mconcat (map (\x -> All (even x)) [2,4,6,7,8])+-- All {getAll = False}+--+-- >>> All True <> mempty+-- All {getAll = True} newtype All = All { getAll :: Bool } deriving ( Eq -- ^ @since 2.01 , Ord -- ^ @since 2.01@@ -183,13 +205,20 @@ instance Monoid All where mempty = All True --- | Boolean monoid under disjunction ('||').+-- | Boolean monoid under disjunction '(||)'. ----- >>> getAny (Any True <> mempty <> Any False)--- True+-- > Any x <> Any y = Any (x || y) ----- >>> getAny (mconcat (map (\x -> Any (even x)) [2,4,6,7,8]))--- True+-- ==== __Examples__+--+-- >>> Any True <> mempty <> Any False+-- Any {getAny = True}+--+-- >>> mconcat (map (\x -> Any (even x)) [2,4,6,7,8])+-- Any {getAny = True}+--+-- >>> Any False <> mempty+-- Any {getAny = False} newtype Any = Any { getAny :: Bool } deriving ( Eq -- ^ @since 2.01 , Ord -- ^ @since 2.01@@ -210,8 +239,15 @@ -- | Monoid under addition. ----- >>> getSum (Sum 1 <> Sum 2 <> mempty)--- 3+-- > Sum a <> Sum b = Sum (a + b)+--+-- ==== __Examples__+--+-- >>> Sum 1 <> Sum 2 <> mempty+-- Sum {getSum = 3}+--+-- >>> mconcat [ Sum n | n <- [3 .. 9]]+-- Sum {getSum = 42} newtype Sum a = Sum { getSum :: a } deriving ( Eq -- ^ @since 2.01 , Ord -- ^ @since 2.01@@ -251,8 +287,15 @@ -- | Monoid under multiplication. ----- >>> getProduct (Product 3 <> Product 4 <> mempty)--- 12+-- > Product x <> Product y == Product (x * y)+--+-- ==== __Examples__+--+-- >>> Product 3 <> Product 4 <> mempty+-- Product {getProduct = 12}+--+-- >>> mconcat [ Product n | n <- [2 .. 10]]+-- Product {getProduct = 3628800} newtype Product a = Product { getProduct :: a } deriving ( Eq -- ^ @since 2.01 , Ord -- ^ @since 2.01@@ -294,11 +337,14 @@ -- | Monoid under '<|>'. ----- >>> getAlt (Alt (Just 12) <> Alt (Just 24))--- Just 12+-- > Alt l <> Alt r == Alt (l <|> r) ----- >>> getAlt $ Alt Nothing <> Alt (Just 24)--- Just 24+-- ==== __Examples__+-- >>> Alt (Just 12) <> Alt (Just 24)+-- Alt {getAlt = Just 12}+--+-- >>> Alt Nothing <> Alt (Just 24)+-- Alt {getAlt = Just 24} -- -- @since 4.8.0.0 newtype Alt f a = Alt {getAlt :: f a}
Data/String.hs view
@@ -37,8 +37,26 @@ import Data.Functor.Identity (Identity (Identity)) import Data.List (lines, words, unlines, unwords) --- | Class for string-like datastructures; used by the overloaded string--- extension (-XOverloadedStrings in GHC).+-- | `IsString` is used in combination with the @-XOverloadedStrings@+-- language extension to convert the literals to different string types.+--+-- For example, if you use the [text](https://hackage.haskell.org/package/text) package,+-- you can say+--+-- @+-- {-# LANGUAGE OverloadedStrings #-}+--+-- myText = "hello world" :: Text+-- @+--+-- Internally, the extension will convert this to the equivalent of+--+-- @+-- myText = fromString @Text ("hello world" :: String)+-- @+--+-- __Note:__ You can use @fromString@ in normal code as well,+-- but the usual performance/memory efficiency problems with 'String' apply. class IsString a where fromString :: String -> a
GHC/Base.hs view
@@ -250,8 +250,16 @@ class Semigroup a where -- | An associative operation. --+ -- ==== __Examples__+ -- -- >>> [1,2,3] <> [4,5,6] -- [1,2,3,4,5,6]+ --+ -- >>> Just [1, 2, 3] <> Just [4, 5, 6]+ -- Just [1,2,3,4,5,6]+ --+ -- >>> putStr "Hello, " <> putStrLn "World!"+ -- Hello, World! (<>) :: a -> a -> a a <> b = sconcat (a :| [ b ]) @@ -260,9 +268,20 @@ -- The default definition should be sufficient, but this can be -- overridden for efficiency. --+ -- ==== __Examples__+ --+ -- For the following examples, we will assume that we have:+ -- -- >>> import Data.List.NonEmpty (NonEmpty (..))+ -- -- >>> sconcat $ "Hello" :| [" ", "Haskell", "!"] -- "Hello Haskell!"+ --+ -- >>> sconcat $ Just [1, 2, 3] :| [Nothing, Just [4, 5, 6]]+ -- Just [1,2,3,4,5,6]+ --+ -- >>> sconcat $ Left 1 :| [Right 2, Left 3, Right 4]+ -- Right 2 sconcat :: NonEmpty a -> a sconcat (a :| as) = go a as where go b (c:cs) = b <> go c cs@@ -270,17 +289,25 @@ -- | Repeat a value @n@ times. --- -- Given that this works on a 'Semigroup' it is allowed to fail if- -- you request 0 or fewer repetitions, and the default definition- -- will do so.+ -- The default definition will raise an exception for a multiplier that is @<= 0@.+ -- This may be overridden with an implementation that is total. For monoids+ -- it is preferred to use 'stimesMonoid'. -- -- By making this a member of the class, idempotent semigroups -- and monoids can upgrade this to execute in \(\mathcal{O}(1)\) by -- picking @stimes = 'Data.Semigroup.stimesIdempotent'@ or @stimes =- -- 'stimesIdempotentMonoid'@ respectively.+ -- 'Data.Semigroup.stimesIdempotentMonoid'@ respectively. --+ -- ==== __Examples__+ -- -- >>> stimes 4 [1] -- [1,1,1,1]+ --+ -- >>> stimes 5 (putStr "hi!")+ -- hi!hi!hi!hi!hi!+ --+ -- >>> stimes 3 (Right ":)")+ -- Right ":)" stimes :: Integral b => b -> a -> a stimes = stimesDefault @@ -314,8 +341,12 @@ class Semigroup a => Monoid a where -- | Identity of 'mappend' --+ -- ==== __Examples__ -- >>> "Hello world" <> mempty -- "Hello world"+ --+ -- >>> mempty <> [1, 2, 3]+ -- [1,2,3] mempty :: a mempty = mconcat [] {-# INLINE mempty #-}@@ -1396,8 +1427,18 @@ -- > map f [x1, x2, ..., xn] == [f x1, f x2, ..., f xn] -- > map f [x1, x2, ...] == [f x1, f x2, ...] --+-- this means that @map id == id@+--+-- ==== __Examples__+-- -- >>> map (+1) [1, 2, 3] -- [2,3,4]+--+-- >>> map id [1, 2, 3]+-- [1,2,3]+--+-- >>> map (\n -> 3 * n + 1) [1, 2, 3]+-- [4,7,10] map :: (a -> b) -> [a] -> [b] {-# NOINLINE [0] map #-} -- We want the RULEs "map" and "map/coerce" to fire first.@@ -1464,21 +1505,33 @@ -- append ---------------------------------------------- --- | Append two lists, i.e.,+-- | '(++)' appends two lists, i.e., -- -- > [x1, ..., xm] ++ [y1, ..., yn] == [x1, ..., xm, y1, ..., yn] -- > [x1, ..., xm] ++ [y1, ...] == [x1, ..., xm, y1, ...] -- -- If the first list is not finite, the result is the first list. --+-- ==== __Performance considerations__+-- -- This function takes linear time in the number of elements of the -- __first__ list. Thus it is better to associate repeated -- applications of '(++)' to the right (which is the default behaviour): -- @xs ++ (ys ++ zs)@ or simply @xs ++ ys ++ zs@, but not @(xs ++ ys) ++ zs@. -- For the same reason 'Data.List.concat' @=@ 'Data.List.foldr' '(++)' @[]@ -- has linear performance, while 'Data.List.foldl' '(++)' @[]@ is prone--- to quadratic slowdown.-+-- to quadratic slowdown+--+-- ==== __Examples__+--+-- >>> [1, 2, 3] ++ [4, 5, 6]+-- [1,2,3,4,5,6]+--+-- >>> [] ++ [1, 2, 3]+-- [1,2,3]+--+-- >>> [3, 2, 1] ++ []+-- [3,2,1] (++) :: [a] -> [a] -> [a] {-# NOINLINE [2] (++) #-} -- Give time for the RULEs for (++) to fire in InitialPhase@@ -1508,10 +1561,42 @@ -- Type Char and String ---------------------------------------------- --- | A 'String' is a list of characters. String constants in Haskell are values--- of type 'String'.+-- | 'String' is an alias for a list of characters. ----- See "Data.List" for operations on lists.+-- String constants in Haskell are values of type 'String'.+-- That means if you write a string literal like @"hello world"@,+-- it will have the type @[Char]@, which is the same as @String@.+--+-- __Note:__ You can ask the compiler to automatically infer different types+-- with the @-XOverloadedStrings@ language extension, for example+-- @"hello world" :: Text@. See t'Data.String.IsString' for more information.+--+-- Because @String@ is just a list of characters, you can use normal list functions+-- to do basic string manipulation. See "Data.List" for operations on lists.+--+-- === __Performance considerations__+--+-- @[Char]@ is a relatively memory-inefficient type.+-- It is a linked list of boxed word-size characters, internally it looks something like:+--+-- > ╭─────┬───┬──╮ ╭─────┬───┬──╮ ╭─────┬───┬──╮ ╭────╮+-- > │ (:) │ │ ─┼─>│ (:) │ │ ─┼─>│ (:) │ │ ─┼─>│ [] │+-- > ╰─────┴─┼─┴──╯ ╰─────┴─┼─┴──╯ ╰─────┴─┼─┴──╯ ╰────╯+-- > v v v+-- > 'a' 'b' 'c'+--+-- The @String@ "abc" will use @5*3+1 = 16@ (in general @5n+1@)+-- words of space in memory.+--+-- Furthermore, operations like '(++)' (string concatenation) are @O(n)@+-- (in the left argument).+--+-- For historical reasons, the @base@ library uses @String@ in a lot of places+-- for the conceptual simplicity, but library code dealing with user-data+-- should use the [text](https://hackage.haskell.org/package/text)+-- package for Unicode text, or the the+-- [bytestring](https://hackage.haskell.org/package/bytestring) package+-- for binary data. type String = [Char] unsafeChr :: Int -> Char@@ -1558,6 +1643,20 @@ -- | Identity function. -- -- > id x = x+--+-- This function might seem useless at first glance, but it can be very useful+-- in a higher order context.+--+-- ==== __Examples__+--+-- >>> length $ filter id [True, True, False, True]+-- 3+--+-- >>> Just (Just 3) >>= id+-- Just 3+--+-- >>> foldr id 0 [(^3), (*5), (+2)]+-- 1000 id :: a -> a id x = x @@ -1591,6 +1690,13 @@ data Opaque = forall a. O a -- | @const x y@ always evaluates to @x@, ignoring its second argument. --+-- > const x = \_ -> x+--+-- This function might seem useless at first glance, but it can be very useful+-- in a higher order context.+--+-- ==== __Examples__+-- -- >>> const 42 "hello" -- 42 --@@ -1599,7 +1705,22 @@ const :: a -> b -> a const x _ = x --- | Function composition.+-- | Right to left function composition.+--+-- prop> (f . g) x = f (g x)+--+-- prop> f . id = f = id . f+--+-- ==== __Examples__+--+-- >>> map ((*2) . length) [[], [0, 1, 2], [0]]+-- [0,6,2]+--+-- >>> foldr (.) id [(+1), (*3), (^3)] 2+-- 25+--+-- >>> let (...) = (.).(.) in ((*2)...(+)) 5 10+-- 30 {-# INLINE (.) #-} -- Make sure it has TWO args only on the left, so that it inlines -- when applied to two functions, even if there is no final argument@@ -1608,8 +1729,17 @@ -- | @'flip' f@ takes its (first) two arguments in the reverse order of @f@. --+-- prop> flip f x y = f y x+--+-- prop> flip . flip = id+--+-- ==== __Examples__+-- -- >>> flip (++) "hello" "world" -- "worldhello"+--+-- >>> let (.>) = flip (.) in (+1) .> show $ 5+-- "6" flip :: (a -> b -> c) -> b -> a -> c flip f x y = f y x @@ -1621,15 +1751,18 @@ -- (\x -> undefined x) `seq` () and thus would just evaluate to (), but now -- it is equivalent to undefined `seq` () which diverges. -{- | @($)@ is the __function application__ operator.+{- | @'($)'@ is the __function application__ operator. -Applying @($)@ to a function @f@ and an argument @x@ gives the same result as applying @f@ to @x@ directly. The definition is akin to this:+Applying @'($)'@ to a function @f@ and an argument @x@ gives the same result as applying @f@ to @x@ directly. The definition is akin to this: @ ($) :: (a -> b) -> a -> b ($) f x = f x @ +This is @'id'@ specialized from @a -> a@ to @(a -> b) -> (a -> b)@ which by the associativity of @(->)@+is the same as @(a -> b) -> a -> b@.+ On the face of it, this may appear pointless! But it's actually one of the most useful and important operators in Haskell. The order of operations is very different between @($)@ and normal function application. Normal function application has precedence 10 - higher than any operator - and associates to the left. So these two definitions are equivalent:@@ -1646,7 +1779,7 @@ expr = (min 5) (1 + 5) @ -=== Uses+==== __Examples__ A common use cases of @($)@ is to avoid parentheses in complex expressions. @@ -1675,7 +1808,7 @@ >>> [6, 32] @ -=== Technical Remark (Representation Polymorphism)+==== __Technical Remark (Representation Polymorphism)__ @($)@ is fully representation-polymorphic. This allows it to also be used with arguments of unlifted and even unboxed kinds, such as unboxed integers:
GHC/IO/Handle/Text.hs view
@@ -174,16 +174,28 @@ -- | Computation 'hGetLine' @hdl@ reads a line from the file or -- channel managed by @hdl@.+-- 'hGetLine' does not return the newline as part of the result. --+-- A line is separated by the newline+-- set with 'System.IO.hSetNewlineMode' or 'nativeNewline' by default.+-- The read newline character(s) are not returned as part of the result.+--+-- If 'hGetLine' encounters end-of-file at any point while reading+-- in the middle of a line, it is treated as a line terminator and the (partial)+-- line is returned.+-- -- This operation may fail with: -- -- * 'isEOFError' if the end of file is encountered when reading -- the /first/ character of the line. ----- If 'hGetLine' encounters end-of-file at any other point while reading--- in a line, it is treated as a line terminator and the (partial)--- line is returned.-+-- ==== __Examples__+--+-- >>> withFile "/home/user/foo" ReadMode hGetLine >>= putStrLn+-- this is the first line of the file :O+--+-- >>> withFile "/home/user/bar" ReadMode (replicateM 3 . hGetLine)+-- ["this is the first line","this is the second line","this is the third line"] hGetLine :: Handle -> IO String hGetLine h = wantReadableHandle_ "hGetLine" h $ \ handle_ ->
GHC/List.hs view
@@ -69,15 +69,16 @@ -- | \(\mathcal{O}(1)\). Extract the first element of a list, which must be non-empty. --+-- ===== __Examples__+-- -- >>> head [1, 2, 3] -- 1+-- -- >>> head [1..] -- 1+-- -- >>> head [] -- *** Exception: Prelude.head: empty list------ WARNING: This function is partial. You can use case-matching, 'uncons' or--- 'listToMaybe' instead. head :: HasCallStack => [a] -> a head (x:_) = x head [] = badHead@@ -105,10 +106,14 @@ -- -- @since 4.8.0.0 --+-- ==== __Examples__+-- -- >>> uncons [] -- Nothing+-- -- >>> uncons [1] -- Just (1,[])+-- -- >>> uncons [1, 2, 3] -- Just (1,[2,3]) uncons :: [a] -> Maybe (a, [a])@@ -121,28 +126,34 @@ -- * If the list is non-empty, returns @'Just' (xs, x)@, -- where @xs@ is the 'init'ial part of the list and @x@ is its 'last' element. ----- @since 4.19.0.0 --+-- 'unsnoc' is dual to 'uncons': for a finite list @xs@+--+-- > unsnoc xs = (\(hd, tl) -> (reverse tl, hd)) <$> uncons (reverse xs)+--+-- ==== __Examples__+-- -- >>> unsnoc [] -- Nothing+-- -- >>> unsnoc [1] -- Just ([],1)+-- -- >>> unsnoc [1, 2, 3] -- Just ([1,2],3) ----- Laziness:+-- ==== __Laziness__ -- -- >>> fst <$> unsnoc [undefined] -- Just []+-- -- >>> head . fst <$> unsnoc (1 : undefined) -- Just *** Exception: Prelude.undefined+-- -- >>> head . fst <$> unsnoc (1 : 2 : undefined) -- Just 1 ----- 'unsnoc' is dual to 'uncons': for a finite list @xs@------ > unsnoc xs = (\(hd, tl) -> (reverse tl, hd)) <$> uncons (reverse xs)---+-- @since 4.19.0.0 unsnoc :: [a] -> Maybe ([a], a) -- The lazy pattern ~(a, b) is important to be productive on infinite lists -- and not to be prone to stack overflows.@@ -153,15 +164,16 @@ -- | \(\mathcal{O}(1)\). Extract the elements after the head of a list, which -- must be non-empty. --+-- ==== __Examples__+-- -- >>> tail [1, 2, 3] -- [2,3]+-- -- >>> tail [1] -- []+-- -- >>> tail [] -- *** Exception: Prelude.tail: empty list------ WARNING: This function is partial. You can use case-matching or 'uncons'--- instead. tail :: HasCallStack => [a] -> [a] tail (_:xs) = xs tail [] = errorEmptyList "tail"@@ -171,14 +183,18 @@ -- | \(\mathcal{O}(n)\). Extract the last element of a list, which must be -- finite and non-empty. --+-- WARNING: This function is partial. Consider using 'unsnoc' instead.+--+-- ==== __Examples__+-- -- >>> last [1, 2, 3] -- 3+-- -- >>> last [1..] -- * Hangs forever *+-- -- >>> last [] -- *** Exception: Prelude.last: empty list------ WARNING: This function is partial. Consider using 'unsnoc' instead. last :: HasCallStack => [a] -> a #if defined(USE_REPORT_PRELUDE) last [x] = x@@ -199,14 +215,18 @@ -- | \(\mathcal{O}(n)\). Return all the elements of a list except the last one. -- The list must be non-empty. --+-- WARNING: This function is partial. Consider using 'unsnoc' instead.+--+-- ==== __Examples__+-- -- >>> init [1, 2, 3] -- [1,2]+-- -- >>> init [1] -- []+-- -- >>> init [] -- *** Exception: Prelude.init: empty list------ WARNING: This function is partial. Consider using 'unsnoc' instead. init :: HasCallStack => [a] -> [a] #if defined(USE_REPORT_PRELUDE) init [x] = []@@ -270,8 +290,16 @@ -- -- > filter p xs = [ x | x <- xs, p x] --+-- ==== __Examples__+-- -- >>> filter odd [1, 2, 3] -- [1,3]+--+-- >>> filter (\l -> length l > 3) ["Hello", ", ", "World", "!"]+-- ["Hello","World"]+--+-- >>> filter (/= 3) [1, 2, 3, 4, 3, 2, 1]+-- [1,2,4,2,1] {-# NOINLINE [1] filter #-} filter :: (a -> Bool) -> [a] -> [a] filter _pred [] = []@@ -478,16 +506,23 @@ -- -- > last (scanl f z xs) == foldl f z xs --+-- ==== __Examples__+-- -- >>> scanl (+) 0 [1..4] -- [0,1,3,6,10]+-- -- >>> scanl (+) 42 [] -- [42]+-- -- >>> scanl (-) 100 [1..4] -- [100,99,97,94,90]+-- -- >>> scanl (\reversedString nextChar -> nextChar : reversedString) "foo" ['a', 'b', 'c', 'd'] -- ["foo","afoo","bafoo","cbafoo","dcbafoo"]+-- -- >>> take 10 (scanl (+) 0 [1..]) -- [0,1,3,6,10,15,21,28,36,45]+-- -- >>> take 1 (scanl undefined 'a' undefined) -- "a" @@ -525,18 +560,26 @@ -- -- > scanl1 f [x1, x2, ...] == [x1, x1 `f` x2, ...] --+-- ==== __Examples__+-- -- >>> scanl1 (+) [1..4] -- [1,3,6,10]+-- -- >>> scanl1 (+) [] -- []+-- -- >>> scanl1 (-) [1..4] -- [1,-1,-4,-8]+-- -- >>> scanl1 (&&) [True, False, True, True] -- [True,False,False,False]+-- -- >>> scanl1 (||) [False, False, True, True] -- [False,False,True,True]+-- -- >>> take 10 (scanl1 (+) [1..]) -- [1,3,6,10,15,21,28,36,45,55]+-- -- >>> take 1 (scanl1 undefined ('a' : undefined)) -- "a" scanl1 :: (a -> a -> a) -> [a] -> [a]@@ -655,14 +698,20 @@ -- -- > head (scanr f z xs) == foldr f z xs. --+-- ==== __Examples__+-- -- >>> scanr (+) 0 [1..4] -- [10,9,7,4,0]+-- -- >>> scanr (+) 42 [] -- [42]+-- -- >>> scanr (-) 100 [1..4] -- [98,-97,99,-96,100]+-- -- >>> scanr (\nextChar reversedString -> nextChar : reversedString) "foo" ['a', 'b', 'c', 'd'] -- ["abcdfoo","bcdfoo","cdfoo","dfoo","foo"]+-- -- >>> force $ scanr (+) 0 [1..] -- *** Exception: stack overflow {-# NOINLINE [1] scanr #-}@@ -720,16 +769,23 @@ -- | \(\mathcal{O}(n)\). 'scanr1' is a variant of 'scanr' that has no starting -- value argument. --+-- ==== __Examples__+-- -- >>> scanr1 (+) [1..4] -- [10,9,7,4]+-- -- >>> scanr1 (+) [] -- []+-- -- >>> scanr1 (-) [1..4] -- [-2,3,-1,4]+-- -- >>> scanr1 (&&) [True, False, True, True] -- [False,False,True,True]+-- -- >>> scanr1 (||) [True, True, False, False] -- [True,True,False,False]+-- -- >>> force $ scanr1 (+) [1..] -- *** Exception: stack overflow scanr1 :: (a -> a -> a) -> [a] -> [a]@@ -789,17 +845,27 @@ -- -- > iterate f x == [x, f x, f (f x), ...] --+-- ==== __Laziness__+-- -- Note that 'iterate' is lazy, potentially leading to thunk build-up if -- the consumer doesn't force each iterate. See 'iterate'' for a strict -- variant of this function. --+-- >>> take 1 $ iterate undefined 42+-- [42]+--+-- ==== __Examples__+-- -- >>> take 10 $ iterate not True -- [True,False,True,False,True,False,True,False,True,False]+-- -- >>> take 10 $ iterate (+3) 42 -- [42,45,48,51,54,57,60,63,66,69]--- >>> take 1 $ iterate undefined 42--- [42] --+-- @iterate id == 'repeat'@:+--+-- >>> take 10 $ iterate id 1+-- [1,1,1,1,1,1,1,1,1,1] {-# NOINLINE [1] iterate #-} iterate :: (a -> a) -> a -> [a] iterate f x = x : iterate f (f x)@@ -823,7 +889,6 @@ -- -- >>> take 1 $ iterate' undefined 42 -- *** Exception: Prelude.undefined--- {-# NOINLINE [1] iterate' #-} iterate' :: (a -> a) -> a -> [a] iterate' f x =@@ -845,8 +910,13 @@ -- | 'repeat' @x@ is an infinite list, with @x@ the value of every element. ----- >>> repeat 17--- [17,17,17,17,17,17,17,17,17...+-- ==== __Examples__+--+-- >>> take 10 $ repeat 17+-- [17,17,17,17,17,17,17,17,17, 17]+--+-- >>> repeat undefined+-- [*** Exception: Prelude.undefined repeat :: a -> [a] {-# INLINE [0] repeat #-} -- The pragma just gives the rules more chance to fire@@ -867,10 +937,14 @@ -- It is an instance of the more general 'Data.List.genericReplicate', -- in which @n@ may be of any integral type. --+-- ==== __Examples__+-- -- >>> replicate 0 True -- []+-- -- >>> replicate (-1) True -- []+-- -- >>> replicate 4 True -- [True,True,True,True] {-# INLINE replicate #-}@@ -881,15 +955,19 @@ -- the infinite repetition of the original list. It is the identity -- on infinite lists. --+-- ==== __Examples__+-- -- >>> cycle [] -- *** Exception: Prelude.cycle: empty list+-- -- >>> take 10 (cycle [42]) -- [42,42,42,42,42,42,42,42,42,42]+-- -- >>> take 10 (cycle [2, 5, 7]) -- [2,5,7,2,5,7,2,5,7,2]+-- -- >>> take 1 (cycle (42 : undefined)) -- [42]--- cycle :: HasCallStack => [a] -> [a] cycle [] = errorEmptyList "cycle" cycle xs = xs' where xs' = xs ++ xs'@@ -897,22 +975,27 @@ -- | 'takeWhile', applied to a predicate @p@ and a list @xs@, returns the -- longest prefix (possibly empty) of @xs@ of elements that satisfy @p@. ----- >>> takeWhile (< 3) [1,2,3,4,1,2,3,4]--- [1,2]--- >>> takeWhile (< 9) [1,2,3]--- [1,2,3]--- >>> takeWhile (< 0) [1,2,3]--- []------ Laziness:+-- ==== __Laziness__ -- -- >>> takeWhile (const False) undefined -- *** Exception: Prelude.undefined+-- -- >>> takeWhile (const False) (undefined : undefined) -- []+-- -- >>> take 1 (takeWhile (const True) (1 : undefined)) -- [1] --+-- ==== __Examples__+--+-- >>> takeWhile (< 3) [1,2,3,4,1,2,3,4]+-- [1,2]+--+-- >>> takeWhile (< 9) [1,2,3]+-- [1,2,3]+--+-- >>> takeWhile (< 0) [1,2,3]+-- [] {-# NOINLINE [1] takeWhile #-} takeWhile :: (a -> Bool) -> [a] -> [a] takeWhile _ [] = []@@ -941,10 +1024,14 @@ -- | 'dropWhile' @p xs@ returns the suffix remaining after 'takeWhile' @p xs@. --+-- ==== __Examples__+-- -- >>> dropWhile (< 3) [1,2,3,4,5,1,2,3] -- [3,4,5,1,2,3]+-- -- >>> dropWhile (< 9) [1,2,3] -- []+-- -- >>> dropWhile (< 0) [1,2,3] -- [1,2,3] dropWhile :: (a -> Bool) -> [a] -> [a]@@ -956,28 +1043,35 @@ -- | 'take' @n@, applied to a list @xs@, returns the prefix of @xs@ -- of length @n@, or @xs@ itself if @n >= 'length' xs@. --+-- It is an instance of the more general 'Data.List.genericTake',+-- in which @n@ may be of any integral type.+--+-- ==== __Laziness__+--+-- >>> take 0 undefined+-- []+-- >>> take 2 (1 : 2 : undefined)+-- [1,2]+--+-- ==== __Examples__+-- -- >>> take 5 "Hello World!" -- "Hello"+-- -- >>> take 3 [1,2,3,4,5] -- [1,2,3]+-- -- >>> take 3 [1,2] -- [1,2]+-- -- >>> take 3 [] -- []+-- -- >>> take (-1) [1,2] -- []--- >>> take 0 [1,2]--- [] ----- Laziness:------ >>> take 0 undefined+-- >>> take 0 [1,2] -- []--- >>> take 1 (1 : undefined)--- [1]------ It is an instance of the more general 'Data.List.genericTake',--- in which @n@ may be of any integral type. take :: Int -> [a] -> [a] #if defined(USE_REPORT_PRELUDE) take n _ | n <= 0 = []@@ -1034,21 +1128,28 @@ -- | 'drop' @n xs@ returns the suffix of @xs@ -- after the first @n@ elements, or @[]@ if @n >= 'length' xs@. --+-- It is an instance of the more general 'Data.List.genericDrop',+-- in which @n@ may be of any integral type.+--+-- ==== __Examples__+-- -- >>> drop 6 "Hello World!" -- "World!"+-- -- >>> drop 3 [1,2,3,4,5] -- [4,5]+-- -- >>> drop 3 [1,2] -- []+-- -- >>> drop 3 [] -- []+-- -- >>> drop (-1) [1,2] -- [1,2]+-- -- >>> drop 0 [1,2] -- [1,2]------ It is an instance of the more general 'Data.List.genericDrop',--- in which @n@ may be of any integral type. drop :: Int -> [a] -> [a] #if defined(USE_REPORT_PRELUDE) drop n xs | n <= 0 = xs@@ -1071,34 +1172,45 @@ -- | 'splitAt' @n xs@ returns a tuple where first element is @xs@ prefix of -- length @n@ and second element is the remainder of the list: --+-- 'splitAt' is an instance of the more general 'Data.List.genericSplitAt',+-- in which @n@ may be of any integral type.+--+-- ==== __Laziness__+--+-- It is equivalent to @('take' n xs, 'drop' n xs)@+-- unless @n@ is @_|_@:+-- @splitAt _|_ xs = _|_@, not @(_|_, _|_)@).+--+-- The first component of the tuple is produced lazily:+--+-- >>> fst (splitAt 0 undefined)+-- []+--+-- >>> take 1 (fst (splitAt 10 (1 : undefined)))+-- [1]+--+-- ==== __Examples__+-- -- >>> splitAt 6 "Hello World!" -- ("Hello ","World!")+-- -- >>> splitAt 3 [1,2,3,4,5] -- ([1,2,3],[4,5])+-- -- >>> splitAt 1 [1,2,3] -- ([1],[2,3])+-- -- >>> splitAt 3 [1,2,3] -- ([1,2,3],[])+-- -- >>> splitAt 4 [1,2,3] -- ([1,2,3],[])+-- -- >>> splitAt 0 [1,2,3] -- ([],[1,2,3])+-- -- >>> splitAt (-1) [1,2,3] -- ([],[1,2,3])------ It is equivalent to @('take' n xs, 'drop' n xs)@--- unless @n@ is @_|_@:--- @splitAt _|_ xs = _|_@, not @(_|_, _|_)@).------ The first component of the tuple is produced lazily:------ >>> fst (splitAt 0 undefined)--- []--- >>> take 1 (fst (splitAt 10 (1 : undefined)))--- [1]------ 'splitAt' is an instance of the more general 'Data.List.genericSplitAt',--- in which @n@ may be of any integral type. splitAt :: Int -> [a] -> ([a],[a]) #if defined(USE_REPORT_PRELUDE)@@ -1120,16 +1232,9 @@ -- first element is the longest prefix (possibly empty) of @xs@ of elements that -- satisfy @p@ and second element is the remainder of the list: ----- >>> span (< 3) [1,2,3,4,1,2,3,4]--- ([1,2],[3,4,1,2,3,4])--- >>> span (< 9) [1,2,3]--- ([1,2,3],[])--- >>> span (< 0) [1,2,3]--- ([],[1,2,3])--- -- 'span' @p xs@ is equivalent to @('takeWhile' p xs, 'dropWhile' p xs)@, even if @p@ is @_|_@. ----- Laziness:+-- ==== __Laziness__ -- -- >>> span undefined [] -- ([],[])@@ -1145,6 +1250,16 @@ -- >>> take 10 (fst (span (const True) [1..])) -- [1,2,3,4,5,6,7,8,9,10] --+-- ==== __Examples__+--+-- >>> span (< 3) [1,2,3,4,1,2,3,4]+-- ([1,2],[3,4,1,2,3,4])+--+-- >>> span (< 9) [1,2,3]+-- ([1,2,3],[])+--+-- >>> span (< 0) [1,2,3]+-- ([],[1,2,3]) span :: (a -> Bool) -> [a] -> ([a],[a]) span _ xs@[] = (xs, xs) span p xs@(x:xs')@@ -1155,25 +1270,21 @@ -- first element is longest prefix (possibly empty) of @xs@ of elements that -- /do not satisfy/ @p@ and second element is the remainder of the list: ----- >>> break (> 3) [1,2,3,4,1,2,3,4]--- ([1,2,3],[4,1,2,3,4])--- >>> break (< 9) [1,2,3]--- ([],[1,2,3])--- >>> break (> 9) [1,2,3]--- ([1,2,3],[])--- -- 'break' @p@ is equivalent to @'span' ('not' . p)@ -- and consequently to @('takeWhile' ('not' . p) xs, 'dropWhile' ('not' . p) xs)@, -- even if @p@ is @_|_@. ----- Laziness:+-- ==== __Laziness__ -- -- >>> break undefined [] -- ([],[])+-- -- >>> fst (break (const True) undefined) -- *** Exception: Prelude.undefined+-- -- >>> fst (break (const True) (undefined : undefined)) -- []+-- -- >>> take 1 (fst (break (const False) (1 : undefined))) -- [1] --@@ -1182,6 +1293,16 @@ -- >>> take 10 (fst (break (const False) [1..])) -- [1,2,3,4,5,6,7,8,9,10] --+-- ==== __Examples__+--+-- >>> break (> 3) [1,2,3,4,1,2,3,4]+-- ([1,2,3],[4,1,2,3,4])+--+-- >>> break (< 9) [1,2,3]+-- ([],[1,2,3])+--+-- >>> break (> 9) [1,2,3]+-- ([1,2,3],[]) break :: (a -> Bool) -> [a] -> ([a],[a]) #if defined(USE_REPORT_PRELUDE) break p = span (not . p)@@ -1193,15 +1314,30 @@ | otherwise = let (ys,zs) = break p xs' in (x:ys,zs) #endif --- | 'reverse' @xs@ returns the elements of @xs@ in reverse order.+-- | \(\mathcal{O}(n)\). 'reverse' @xs@ returns the elements of @xs@ in reverse order. -- @xs@ must be finite. --+-- ==== __Laziness__+--+-- 'reverse' is lazy in its elements.+--+-- >>> head (reverse [undefined, 1])+-- 1+--+-- >>> reverse (1 : 2 : undefined)+-- *** Exception: Prelude.undefined+--+-- ==== __Examples__+-- -- >>> reverse [] -- []+-- -- >>> reverse [42] -- [42]+-- -- >>> reverse [2,5,7] -- [7,5,2]+-- -- >>> reverse [1..] -- * Hangs forever * reverse :: [a] -> [a]@@ -1218,16 +1354,23 @@ -- 'True', the list must be finite; 'False', however, results from a 'False' -- value at a finite index of a finite or infinite list. --+-- ==== __Examples__+-- -- >>> and [] -- True+-- -- >>> and [True] -- True+-- -- >>> and [False] -- False+-- -- >>> and [True, True, False] -- False+-- -- >>> and (False : repeat True) -- Infinite list [False,True,True,True,True,True,True... -- False+-- -- >>> and (repeat True) -- * Hangs forever * and :: [Bool] -> Bool@@ -1248,16 +1391,23 @@ -- 'False', the list must be finite; 'True', however, results from a 'True' -- value at a finite index of a finite or infinite list. --+-- ==== __Examples__+-- -- >>> or [] -- False+-- -- >>> or [True] -- True+-- -- >>> or [False] -- False+-- -- >>> or [True, True, False] -- True+-- -- >>> or (True : repeat False) -- Infinite list [True,False,False,False,False,False,False... -- True+-- -- >>> or (repeat False) -- * Hangs forever * or :: [Bool] -> Bool@@ -1280,14 +1430,20 @@ -- value for the predicate applied to an element at a finite index of a finite -- or infinite list. --+-- ==== __Examples__+-- -- >>> any (> 3) [] -- False+-- -- >>> any (> 3) [1,2] -- False+-- -- >>> any (> 3) [1,2,3,4,5] -- True+-- -- >>> any (> 3) [1..] -- True+-- -- >>> any (> 3) [0, -1..] -- * Hangs forever * any :: (a -> Bool) -> [a] -> Bool@@ -1311,14 +1467,20 @@ -- value for the predicate applied to an element at a finite index of a finite -- or infinite list. --+-- ==== __Examples__+-- -- >>> all (> 3) [] -- True+-- -- >>> all (> 3) [1,2] -- False+-- -- >>> all (> 3) [1,2,3,4,5] -- False+-- -- >>> all (> 3) [1..] -- False+-- -- >>> all (> 3) [4..] -- * Hangs forever * all :: (a -> Bool) -> [a] -> Bool@@ -1341,14 +1503,20 @@ -- 'False', the list must be finite; 'True', however, results from an element -- equal to @x@ found at a finite index of a finite or infinite list. --+-- ==== __Examples__+-- -- >>> 3 `elem` [] -- False+-- -- >>> 3 `elem` [1,2] -- False+-- -- >>> 3 `elem` [1,2,3,4,5] -- True+-- -- >>> 3 `elem` [1..] -- True+-- -- >>> 3 `elem` [4..] -- * Hangs forever * elem :: (Eq a) => a -> [a] -> Bool@@ -1366,14 +1534,20 @@ -- | 'notElem' is the negation of 'elem'. --+-- ==== __Examples__+-- -- >>> 3 `notElem` [] -- True+-- -- >>> 3 `notElem` [1,2] -- True+-- -- >>> 3 `notElem` [1,2,3,4,5] -- False+-- -- >>> 3 `notElem` [1..] -- False+-- -- >>> 3 `notElem` [4..] -- * Hangs forever * notElem :: (Eq a) => a -> [a] -> Bool@@ -1393,13 +1567,16 @@ -- list. -- For the result to be 'Nothing', the list must be finite. --+-- ==== __Examples__+-- -- >>> lookup 2 [] -- Nothing+-- -- >>> lookup 2 [(1, "first")] -- Nothing+-- -- >>> lookup 2 [(1, "first"), (2, "second"), (3, "third")] -- Just "second"--- lookup :: (Eq a) => a -> [(a,b)] -> Maybe b lookup _key [] = Nothing lookup key ((x,y):xys)@@ -1411,10 +1588,16 @@ -- -- > concatMap f xs == (concat . map f) xs --+-- ==== __Examples__+-- -- >>> concatMap (\i -> [-i,i]) [] -- []--- >>> concatMap (\i -> [-i,i]) [1,2,3]+--+-- >>> concatMap (\i -> [-i, i]) [1, 2, 3] -- [-1,1,-2,2,-3,3]+--+-- >>> concatMap ('replicate' 3) [0, 2, 4]+-- [0,0,0,2,2,2,4,4,4] concatMap :: (a -> [b]) -> [a] -> [b] concatMap f = foldr ((++) . f) [] @@ -1428,12 +1611,16 @@ -- | Concatenate a list of lists. --+-- ==== __Examples__+--+-- >>> concat [[1,2,3], [4,5], [6], []]+-- [1,2,3,4,5,6]+-- -- >>> concat [] -- []+-- -- >>> concat [[42]] -- [42]--- >>> concat [[1,2,3], [4,5], [6], []]--- [1,2,3,4,5,6] concat :: [[a]] -> [a] concat = foldr (++) [] @@ -1449,19 +1636,24 @@ -- It is an instance of the more general 'Data.List.genericIndex', -- which takes an index of any integral type. --+-- WARNING: This function is partial, and should only be used if you are+-- sure that the indexing will not fail. Otherwise, use 'Data.List.!?'.+--+-- WARNING: This function takes linear time in the index.+--+-- ==== __Examples__+-- -- >>> ['a', 'b', 'c'] !! 0 -- 'a'+-- -- >>> ['a', 'b', 'c'] !! 2 -- 'c'+-- -- >>> ['a', 'b', 'c'] !! 3 -- *** Exception: Prelude.!!: index too large+-- -- >>> ['a', 'b', 'c'] !! (-1) -- *** Exception: Prelude.!!: negative index------ WARNING: This function is partial, and should only be used if you are--- sure that the indexing will not fail. Otherwise, use 'Data.List.!?'.------ WARNING: This function takes linear time in the index. #if defined(USE_REPORT_PRELUDE) (!!) :: [a] -> Int -> a xs !! n | n < 0 = errorWithoutStackTrace "Prelude.!!: negative index"@@ -1493,18 +1685,23 @@ -- | List index (subscript) operator, starting from 0. Returns 'Nothing' -- if the index is out of bounds --+-- This is the total variant of the partial '!!' operator.+--+-- WARNING: This function takes linear time in the index.+--+-- ==== __Examples__+-- -- >>> ['a', 'b', 'c'] !? 0 -- Just 'a'+-- -- >>> ['a', 'b', 'c'] !? 2 -- Just 'c'+-- -- >>> ['a', 'b', 'c'] !? 3 -- Nothing+-- -- >>> ['a', 'b', 'c'] !? (-1) -- Nothing------ This is the total variant of the partial '!!' operator.------ WARNING: This function takes linear time in the index. (!?) :: [a] -> Int -> Maybe a {-# INLINABLE (!?) #-}@@ -1615,31 +1812,36 @@ -- | \(\mathcal{O}(\min(m,n))\). 'zip' takes two lists and returns a list of -- corresponding pairs. ----- >>> zip [1, 2] ['a', 'b']--- [(1,'a'),(2,'b')]+-- 'zip' is right-lazy: --+-- >>> zip [] undefined+-- []+-- >>> zip undefined []+-- *** Exception: Prelude.undefined+-- ...+--+-- 'zip' is capable of list fusion, but it is restricted to its+-- first list argument and its resulting list.+--+-- ==== __Examples__+--+-- >>> zip [1, 2, 3] ['a', 'b', 'c']+-- [(1,'a'),(2,'b'),(3,'c')]+-- -- If one input list is shorter than the other, excess elements of the longer -- list are discarded, even if one of the lists is infinite: -- -- >>> zip [1] ['a', 'b'] -- [(1,'a')]+-- -- >>> zip [1, 2] ['a'] -- [(1,'a')]+-- -- >>> zip [] [1..] -- []--- >>> zip [1..] []--- [] ----- 'zip' is right-lazy:------ >>> zip [] undefined+-- >>> zip [1..] [] -- []--- >>> zip undefined []--- *** Exception: Prelude.undefined--- ...------ 'zip' is capable of list fusion, but it is restricted to its--- first list argument and its resulting list. {-# NOINLINE [1] zip #-} -- See Note [Fusion for zipN/zipWithN] zip :: [a] -> [b] -> [(a,b)] zip [] _bs = []@@ -1686,12 +1888,7 @@ -- > zipWith (,) xs ys == zip xs ys -- > zipWith f [x1,x2,x3..] [y1,y2,y3..] == [f x1 y1, f x2 y2, f x3 y3..] ----- For example, @'zipWith' (+)@ is applied to two lists to produce the list of--- corresponding sums: ----- >>> zipWith (+) [1, 2, 3] [4, 5, 6]--- [5,7,9]--- -- 'zipWith' is right-lazy: -- -- >>> let f = undefined@@ -1700,6 +1897,17 @@ -- -- 'zipWith' is capable of list fusion, but it is restricted to its -- first list argument and its resulting list.+--+-- ==== __Examples__+--+-- @'zipWith' '(+)'@ can be applied to two lists to produce the list of+-- corresponding sums:+--+-- >>> zipWith (+) [1, 2, 3] [4, 5, 6]+-- [5,7,9]+--+-- >>> zipWith (++) ["hello ", "foo"] ["world!", "bar"]+-- ["hello world!","foobar"] {-# NOINLINE [1] zipWith #-} -- See Note [Fusion for zipN/zipWithN] zipWith :: (a->b->c) -> [a]->[b]->[c] zipWith f = go@@ -1719,7 +1927,7 @@ "zipWithList" [1] forall f. foldr2 (zipWithFB (:) f) [] = zipWith f #-} --- | The 'zipWith3' function takes a function which combines three+-- | \(\mathcal{O}(\min(l,m,n))\). The 'zipWith3' function takes a function which combines three -- elements, as well as three lists and returns a list of the function applied -- to corresponding elements, analogous to 'zipWith'. -- It is capable of list fusion, but it is restricted to its@@ -1727,6 +1935,14 @@ -- -- > zipWith3 (,,) xs ys zs == zip3 xs ys zs -- > zipWith3 f [x1,x2,x3..] [y1,y2,y3..] [z1,z2,z3..] == [f x1 y1 z1, f x2 y2 z2, f x3 y3 z3..]+--+-- ==== __Examples__+--+-- >>> zipWith3 (\x y z -> [x, y, z]) "123" "abc" "xyz"+-- ["1ax","2by","3cz"]+--+-- >>> zipWith3 (\x y z -> (x * y) + z) [1, 2, 3] [4, 5, 6] [7, 8, 9]+-- [11,18,27] {-# NOINLINE [1] zipWith3 #-} zipWith3 :: (a->b->c->d) -> [a]->[b]->[c]->[d] zipWith3 z = go@@ -1746,8 +1962,11 @@ -- | 'unzip' transforms a list of pairs into a list of first components -- and a list of second components. --+-- ==== __Examples__+-- -- >>> unzip [] -- ([],[])+-- -- >>> unzip [(1, 'a'), (2, 'b')] -- ([1,2],"ab") unzip :: [(a,b)] -> ([a],[b])@@ -1757,10 +1976,13 @@ unzip = foldr (\(a,b) ~(as,bs) -> (a:as,b:bs)) ([],[]) -- | The 'unzip3' function takes a list of triples and returns three--- lists, analogous to 'unzip'.+-- lists of the respective components, analogous to 'unzip'. --+-- ==== __Examples__+-- -- >>> unzip3 [] -- ([],[],[])+-- -- >>> unzip3 [(1, 'a', True), (2, 'b', False)] -- ([1,2],"ab",[True,False]) unzip3 :: [(a,b,c)] -> ([a],[b],[c])
System/Posix/Internals.hs view
@@ -517,7 +517,7 @@ c_isatty :: CInt -> IO CInt foreign import javascript interruptible "h$base_lseek" c_lseek :: CInt -> COff -> CInt -> IO COff-foreign import javascript interruptible "h$base_lstat" -- fixme wrong type+foreign import javascript interruptible "h$base_lstat" lstat :: CFilePath -> Ptr CStat -> IO CInt foreign import javascript interruptible "h$base_open" c_open :: CFilePath -> CInt -> CMode -> IO CInt
base.cabal view
@@ -1,6 +1,6 @@ cabal-version: 3.0 name: base-version: 4.19.0.0+version: 4.19.1.0 -- NOTE: Don't forget to update ./changelog.md license: BSD-3-Clause
changelog.md view
@@ -1,5 +1,10 @@ # Changelog for [`base` package](http://hackage.haskell.org/package/base) +## 4.19.1.0 *October 2023*+ * Shipped with GHC 9.8.2+ * Improve documentation of various functions+ * Implement primitives like `lstat` and `rmdir`, for the JS backend.+ ## 4.19.0.0 *October 2023* * Shipped with GHC 9.8.1@@ -40,7 +45,8 @@ * Deprecate `Data.List.NonEmpty.unzip` ([CLC proposal #86](https://github.com/haskell/core-libraries-committee/issues/86)) * Fixed exponent overflow/underflow bugs in the `Read` instances for `Float` and `Double` ([CLC proposal #192](https://github.com/haskell/core-libraries-committee/issues/192)) * Implement `copyBytes`, `fillBytes`, `moveBytes` and `stimes` for `Data.Array.Byte.ByteArray` using primops ([CLC proposal #188](https://github.com/haskell/core-libraries-committee/issues/188))- * Add rewrite rules for conversion between `Int64`/`Word64` and `Float`/`Double` on 64-bit architectures ([CLC proposal #203](https://github.com/haskell/core-libraries-committee/issues/203)).+ * Add rewrite rules for conversion between `Int64` / `Word64` and `Float` / `Double` on 64-bit architectures ([CLC proposal #203](https://github.com/haskell/core-libraries-committee/issues/203)).+ * `Generic` instances for tuples now expose `Unit`, `Tuple2`, `Tuple3`, ..., `Tuple64` as the actual names for tuple type constructors ([GHC proposal #475](https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0475-tuple-syntax.rst)). ## 4.18.0.0 *March 2023*
jsbits/base.js view
@@ -247,6 +247,39 @@ h$unsupported(-1, c); } +function h$lstat(file, file_off, stat, stat_off) {+ TRACE_IO("lstat")+#ifndef GHCJS_BROWSER+ if(h$isNode()) {+ try {+ var fs = h$fs.lstatSync(h$decodeUtf8z(file, file_off));+ h$base_fillStat(fs, stat, stat_off);+ return 0;+ } catch(e) {+ h$setErrno(e);+ return -1;+ }+ } else+#endif+ h$unsupported(-1);+}++function h$rmdir(file, file_off) {+ TRACE_IO("rmdir")+#ifndef GHCJS_BROWSER+ if(h$isNode()) {+ try {+ var fs = h$fs.rmdirSync(h$decodeUtf8z(file, file_off));+ return 0;+ } catch(e) {+ h$setErrno(e);+ return -1;+ }+ } else+#endif+ h$unsupported(-1);+}+ function h$rename(old_path, old_path_off, new_path, new_path_off) { TRACE_IO("rename") #ifndef GHCJS_BROWSER@@ -554,21 +587,32 @@ const h$base_o_binary = 0x00000; const h$base_at_fdcwd = -100; +function h$base_stat_check_mode(mode,p) {+ // inspired by Node's checkModeProperty+ var r = (mode & h$fs.constants.S_IFMT) === p;+ return r ? 1 : 0;+} +function h$base_stat_check_mode(mode,p) {+ // inspired by Node's checkModeProperty+ var r = (mode & h$fs.constants.S_IFMT) === p;+ return r ? 1 : 0;+}+ function h$base_c_s_isreg(mode) {- return 1;+ return h$base_stat_check_mode(mode,h$fs.constants.S_IFREG); } function h$base_c_s_ischr(mode) {- return 0;+ return h$base_stat_check_mode(mode,h$fs.constants.S_IFCHR); } function h$base_c_s_isblk(mode) {- return 0;+ return h$base_stat_check_mode(mode,h$fs.constants.S_IFBLK); } function h$base_c_s_isdir(mode) {- return 0; // fixme+ return h$base_stat_check_mode(mode,h$fs.constants.S_IFDIR); } function h$base_c_s_isfifo(mode) {- return 0;+ return h$base_stat_check_mode(mode,h$fs.constants.S_IFIFO); } function h$base_c_fcntl_read(fd,cmd) { return -1;