src/Tools/Haskell/Haskell.thy
changeset 74136 7bbac3eb8adf
parent 74135 6a16f7a67193
child 74137 49fd45ffd43f
equal deleted inserted replaced
74135:6a16f7a67193 74136:7bbac3eb8adf
   312 
   312 
   313 class (IsString a, Monoid a, Eq a, Ord a) => StringLike a where
   313 class (IsString a, Monoid a, Eq a, Ord a) => StringLike a where
   314   space_explode :: Char -> a -> [a]
   314   space_explode :: Char -> a -> [a]
   315   trim_line :: a -> a
   315   trim_line :: a -> a
   316 
   316 
       
   317 gen_trim_line :: Int -> (Int -> Char) -> (Int -> a -> a) -> a -> a
       
   318 gen_trim_line n at trim s =
       
   319   if n >= 2 && at (n - 2) == '\r' && at (n - 1) == '\n' then trim (n - 2) s
       
   320   else if n >= 1 && Symbol.is_ascii_line_terminator (at (n - 1)) then trim (n - 1) s
       
   321   else s
       
   322 
   317 instance StringLike String where
   323 instance StringLike String where
   318   space_explode :: Char -> String -> [String]
   324   space_explode :: Char -> String -> [String]
   319   space_explode c = Split.split (Split.dropDelims (Split.whenElt (== c)))
   325   space_explode c = Split.split (Split.dropDelims (Split.whenElt (== c)))
   320   trim_line :: String -> String
   326   trim_line :: String -> String
   321   trim_line s =
   327   trim_line s = gen_trim_line (length s) ((!!) s) take s
   322     if not (null s) && Symbol.is_ascii_line_terminator (last s) then
       
   323       case reverse s of
       
   324         '\n' : '\r' : rest -> reverse rest
       
   325         '\r' : rest -> reverse rest
       
   326         '\n' : rest -> reverse rest
       
   327         _ -> s
       
   328     else s
       
   329 
   328 
   330 instance StringLike Text where
   329 instance StringLike Text where
   331   space_explode :: Char -> Text -> [Text]
   330   space_explode :: Char -> Text -> [Text]
   332   space_explode c str =
   331   space_explode c str =
   333     if Text.null str then []
   332     if Text.null str then []
   334     else if Text.all (/= c) str then [str]
   333     else if Text.all (/= c) str then [str]
   335     else map Text.pack $ space_explode c $ Text.unpack str
   334     else map Text.pack $ space_explode c $ Text.unpack str
   336   trim_line :: Text -> Text
   335   trim_line :: Text -> Text
   337   trim_line s =
   336   trim_line s = gen_trim_line (Text.length s) (Text.index s) Text.take s
   338     if n >= 2 && at (n - 2) == '\r' && at (n - 1) == '\n' then Text.take (n - 2) s
       
   339     else if n >= 1 && Symbol.is_ascii_line_terminator (at (n - 1)) then Text.take (n - 1) s
       
   340     else s
       
   341     where
       
   342       n = Text.length s
       
   343       at = Text.index s
       
   344 
   337 
   345 instance StringLike Lazy.Text where
   338 instance StringLike Lazy.Text where
   346   space_explode :: Char -> Lazy.Text -> [Lazy.Text]
   339   space_explode :: Char -> Lazy.Text -> [Lazy.Text]
   347   space_explode c str =
   340   space_explode c str =
   348     if Lazy.null str then []
   341     if Lazy.null str then []
   362         explode rest =
   355         explode rest =
   363           case span (/= (Bytes.byte c)) rest of
   356           case span (/= (Bytes.byte c)) rest of
   364             (_, []) -> [Bytes.pack rest]
   357             (_, []) -> [Bytes.pack rest]
   365             (prfx, _ : rest') -> Bytes.pack prfx : explode rest'
   358             (prfx, _ : rest') -> Bytes.pack prfx : explode rest'
   366   trim_line :: Bytes -> Bytes
   359   trim_line :: Bytes -> Bytes
   367   trim_line s =
   360   trim_line s = gen_trim_line (Bytes.length s) (Bytes.char . Bytes.index s) Bytes.take s
   368     if n >= 2 && at (n - 2) == '\r' && at (n - 1) == '\n' then Bytes.take (n - 2) s
       
   369     else if n >= 1 && Symbol.is_ascii_line_terminator (at (n - 1)) then Bytes.take (n - 1) s
       
   370     else s
       
   371     where
       
   372       n = Bytes.length s
       
   373       at = Bytes.char . Bytes.index s
       
   374 
   361 
   375 class StringLike a => STRING a where make_string :: a -> String
   362 class StringLike a => STRING a where make_string :: a -> String
   376 instance STRING String where make_string = id
   363 instance STRING String where make_string = id
   377 instance STRING Text where make_string = Text.unpack
   364 instance STRING Text where make_string = Text.unpack
   378 instance STRING Lazy.Text where make_string = Lazy.unpack
   365 instance STRING Lazy.Text where make_string = Lazy.unpack