Safe Haskell | None |
---|---|
Language | Haskell2010 |
Synopsis
- data SearchFunctions a = SearchFunctions {}
- makeMatcher :: forall a. Lens' (SearchFunctions a) (Text -> Maybe (Matcher a))
- lister :: forall a n. KnownNat n => SimpleGetter (SearchFunctions a) (MatcherSized n a -> Vector Text -> Vector Int -> (Vector Int, Vector (Indices n)))
- displayer :: forall a n. KnownNat n => SimpleGetter (SearchFunctions a) (MatcherSized n a -> Text -> Vector n Int -> [Text])
- searchFunctionsFuzzy :: SearchFunctions MatchPart
- searchFunctionsOL :: SearchFunctions Int
- searchWithMatcher :: SearchFunctions a -> Vector Text -> Maybe Text -> Vector Int -> (Vector Int, (Int, Vector [Text]))
- readVectorStdIn :: IO (Vector Text)
- fileNamesSorted :: Handle -> IO (Vector Text)
- readVectorHandle :: Handle -> IO (Vector Text)
- readVectorHandleWith :: (Text -> Text) -> (Vector Text -> Vector Text) -> Handle -> IO (Vector Text)
- emptyIndices :: Int -> Vector (Indices 0)
- data Handle
- isEOF :: IO Bool
- hIsEOF :: Handle -> IO Bool
- hClose :: Handle -> IO ()
- stdin :: Handle
- finally :: IO a -> IO b -> IO a
- bracket :: IO a -> (a -> IO b) -> (a -> IO c) -> IO c
- data AsyncException
- catch :: Exception e => IO a -> (e -> IO a) -> IO a
- (^.) :: s -> Getting a s a -> a
- (?~) :: ASetter s t a (Maybe b) -> b -> s -> t
- set :: ASetter s t a b -> b -> s -> t
- (.~) :: ASetter s t a b -> b -> s -> t
- over :: ASetter s t a b -> (a -> b) -> s -> t
- (%~) :: ASetter s t a b -> (a -> b) -> s -> t
- _1 :: Field1 s t a b => Lens s t a b
- _2 :: Field2 s t a b => Lens s t a b
- _3 :: Field3 s t a b => Lens s t a b
- type ASetter' s a = ASetter s s a a
- makeLenses :: Name -> DecsQ
Search
data SearchFunctions a Source #
SearchFunctions | |
|
makeMatcher :: forall a. Lens' (SearchFunctions a) (Text -> Maybe (Matcher a)) Source #
lister :: forall a n. KnownNat n => SimpleGetter (SearchFunctions a) (MatcherSized n a -> Vector Text -> Vector Int -> (Vector Int, Vector (Indices n))) Source #
displayer :: forall a n. KnownNat n => SimpleGetter (SearchFunctions a) (MatcherSized n a -> Text -> Vector n Int -> [Text]) Source #
searchFunctionsFuzzy :: SearchFunctions MatchPart Source #
Search functions suitable for fuzzy matching. The candidate c
will match the query s
if c
contains all the characters in s
in order. In general there
can be several ways of matching. This tries to find a match with the minimum number of parts. It does not find the minimum number of parts, if that requires
reducing the extent of the partial match during search. E.g. matching "as"
against "talash"
the split will be ["tal","as","h"]
and not
["t","a","la","s","h"]
. While matching "talash best match testing hat"
against "tea"
will not result in ["talash best match ","te","sting h","a","t"]
since
"te"
occurs only after we have match all three letters and we can't know if we will find the "a"
without going through the string.
searchFunctionsOL :: SearchFunctions Int Source #
Search functions that match the words in i.e. space separated substring in any order. "talash best"
will match "be as"
with the split
["tal","as","h","be","st"]
but "talash best" will not match "bet"
.
:: SearchFunctions a | The configuration to use to carry out the search. |
-> Vector Text | The vector |
-> Maybe Text | The query string |
-> Vector Int | The subset of indices of |
-> (Vector Int, (Int, Vector [Text])) | The indices of the matched candidates (see the note above) and the matched candidates broken up according to the match. |
searchWithMatcher carries out one step of the search. Note that the search can stops before going through the whole vector of text. In that case the returned vector of indices should contain not only the indices matched candidates but also the indices of candidates that weren't tested for a match.
Help for reading vectors
readVectorStdIn :: IO (Vector Text) Source #
Read a vector of newline separated candidates from the stdin.
fileNamesSorted :: Handle -> IO (Vector Text) Source #
Read a vector of filenames from the handle, get the basename by removing the path of the directory. Finally sort and deduplicate the resulting filenames. Useful to get the list of executables from PATH for example.
readVectorHandle :: Handle -> IO (Vector Text) Source #
Read a vector of newline separated candidates from a handle.
:: (Text -> Text) | The function to transform the candidates. |
-> (Vector Text -> Vector Text) | The function to apply to the constructed vector before compacting. |
-> Handle | The handle to read from |
-> IO (Vector Text) |
A generalized version of readVectorHandle allowing for the transformation of candidates and the resulting vector. See fileNamesSorted for an example of use.
Exports
Haskell defines operations to read and write characters from and to files,
represented by values of type Handle
. Each value of this type is a
handle: a record used by the Haskell run-time system to manage I/O
with file system objects. A handle has at least the following properties:
- whether it manages input or output or both;
- whether it is open, closed or semi-closed;
- whether the object is seekable;
- whether buffering is disabled, or enabled on a line or block basis;
- a buffer (whose length may be zero).
Most handles will also have a current I/O position indicating where the next
input or output operation will occur. A handle is readable if it
manages only input or both input and output; likewise, it is writable if
it manages only output or both input and output. A handle is open when
first allocated.
Once it is closed it can no longer be used for either input or output,
though an implementation cannot re-use its storage while references
remain to it. Handles are in the Show
and Eq
classes. The string
produced by showing a handle is system dependent; it should include
enough information to identify the handle for debugging. A handle is
equal according to ==
only to itself; no attempt
is made to compare the internal state of different handles for equality.
For a readable handle hdl
, hIsEOF
hdl
returns
True
if no further input can be taken from hdl
or for a
physical file, if the current I/O position is equal to the length of
the file. Otherwise, it returns False
.
NOTE: hIsEOF
may block, because it has to attempt to read from
the stream to determine whether there is any more data to be read.
Computation hClose
hdl
makes handle hdl
closed. Before the
computation finishes, if hdl
is writable its buffer is flushed as
for hFlush
.
Performing hClose
on a handle that has already been closed has no effect;
doing so is not an error. All other operations on a closed handle will fail.
If hClose
fails for any reason, any further operations (apart from
hClose
) on the handle will still fail as if hdl
had been successfully
closed.
:: IO a | computation to run first |
-> IO b | computation to run afterward (even if an exception was raised) |
-> IO a |
A specialised variant of bracket
with just a computation to run
afterward.
:: IO a | computation to run first ("acquire resource") |
-> (a -> IO b) | computation to run last ("release resource") |
-> (a -> IO c) | computation to run in-between |
-> IO c |
When you want to acquire a resource, do some work with it, and
then release the resource, it is a good idea to use bracket
,
because bracket
will install the necessary exception handler to
release the resource in the event that an exception is raised
during the computation. If an exception is raised, then bracket
will
re-raise the exception (after performing the release).
A common example is opening a file:
bracket (openFile "filename" ReadMode) (hClose) (\fileHandle -> do { ... })
The arguments to bracket
are in this order so that we can partially apply
it, e.g.:
withFile name mode = bracket (openFile name mode) hClose
data AsyncException #
Asynchronous exceptions.
Instances
Eq AsyncException | Since: base-4.2.0.0 |
Defined in GHC.IO.Exception (==) :: AsyncException -> AsyncException -> Bool # (/=) :: AsyncException -> AsyncException -> Bool # | |
Ord AsyncException | Since: base-4.2.0.0 |
Defined in GHC.IO.Exception compare :: AsyncException -> AsyncException -> Ordering # (<) :: AsyncException -> AsyncException -> Bool # (<=) :: AsyncException -> AsyncException -> Bool # (>) :: AsyncException -> AsyncException -> Bool # (>=) :: AsyncException -> AsyncException -> Bool # max :: AsyncException -> AsyncException -> AsyncException # min :: AsyncException -> AsyncException -> AsyncException # | |
Show AsyncException | Since: base-4.1.0.0 |
Defined in GHC.IO.Exception showsPrec :: Int -> AsyncException -> ShowS # show :: AsyncException -> String # showList :: [AsyncException] -> ShowS # | |
Exception AsyncException | Since: base-4.7.0.0 |
Defined in GHC.IO.Exception |
:: Exception e | |
=> IO a | The computation to run |
-> (e -> IO a) | Handler to invoke if an exception is raised |
-> IO a |
This is the simplest of the exception-catching functions. It takes a single argument, runs it, and if an exception is raised the "handler" is executed, with the value of the exception passed as an argument. Otherwise, the result is returned as normal. For example:
catch (readFile f) (\e -> do let err = show (e :: IOException) hPutStr stderr ("Warning: Couldn't open " ++ f ++ ": " ++ err) return "")
Note that we have to give a type signature to e
, or the program
will not typecheck as the type is ambiguous. While it is possible
to catch exceptions of any type, see the section "Catching all
exceptions" (in Control.Exception) for an explanation of the problems with doing so.
For catching exceptions in pure (non-IO
) expressions, see the
function evaluate
.
Note that due to Haskell's unspecified evaluation order, an
expression may throw one of several possible exceptions: consider
the expression (error "urk") + (1 `div` 0)
. Does
the expression throw
ErrorCall "urk"
, or DivideByZero
?
The answer is "it might throw either"; the choice is
non-deterministic. If you are catching any type of exception then you
might catch either. If you are calling catch
with type
IO Int -> (ArithException -> IO Int) -> IO Int
then the handler may
get run with DivideByZero
as an argument, or an ErrorCall "urk"
exception may be propogated further up. If you call it again, you
might get a the opposite behaviour. This is ok, because catch
is an
IO
computation.
(^.) :: s -> Getting a s a -> a infixl 8 #
(^.
) applies a getter to a value; in other words, it gets a value out of a structure using a getter (which can be a lens, traversal, fold, etc.).
Getting 1st field of a tuple:
(^.
_1
) :: (a, b) -> a (^.
_1
) =fst
When (^.
) is used with a traversal, it combines all results using the Monoid
instance for the resulting type. For instance, for lists it would be simple concatenation:
>>>
("str","ing") ^. each
"string"
The reason for this is that traversals use Applicative
, and the Applicative
instance for Const
uses monoid concatenation to combine “effects” of Const
.
A non-operator version of (^.
) is called view
, and it's a bit more general than (^.
) (it works in MonadReader
). If you need the general version, you can get it from microlens-mtl; otherwise there's view
available in Lens.Micro.Extras.
over :: ASetter s t a b -> (a -> b) -> s -> t #
Getting fmap
in a roundabout way:
over
mapped
::Functor
f => (a -> b) -> f a -> f bover
mapped
=fmap
Applying a function to both components of a pair:
over
both
:: (a -> b) -> (a, a) -> (b, b)over
both
= \f t -> (f (fst t), f (snd t))
Using
as a replacement for over
_2
second
:
>>>
over _2 show (10,20)
(10,"20")
(%~) :: ASetter s t a b -> (a -> b) -> s -> t infixr 4 #
(%~
) applies a function to the target; an alternative explanation is that it is an inverse of sets
, which turns a setter into an ordinary function.
is the same thing as mapped
%~
reverse
.fmap
reverse
See over
if you want a non-operator synonym.
Negating the 1st element of a pair:
>>>
(1,2) & _1 %~ negate
(-1,2)
Turning all Left
s in a list to upper case:
>>>
(mapped._Left.mapped %~ toUpper) [Left "foo", Right "bar"]
[Left "FOO",Right "bar"]
_1 :: Field1 s t a b => Lens s t a b #
Gives access to the 1st field of a tuple (up to 5-tuples).
Getting the 1st component:
>>>
(1,2,3,4,5) ^. _1
1
Setting the 1st component:
>>>
(1,2,3) & _1 .~ 10
(10,2,3)
Note that this lens is lazy, and can set fields even of undefined
:
>>>
set _1 10 undefined :: (Int, Int)
(10,*** Exception: Prelude.undefined
This is done to avoid violating a lens law stating that you can get back what you put:
>>>
view _1 . set _1 10 $ (undefined :: (Int, Int))
10
The implementation (for 2-tuples) is:
_1
f t = (,)<$>
f (fst
t)<*>
pure
(snd
t)
or, alternatively,
_1
f ~(a,b) = (\a' -> (a',b))<$>
f a
(where ~
means a lazy pattern).
makeLenses :: Name -> DecsQ #
Generate lenses for a data type or a newtype.
To use it, you have to enable Template Haskell first:
{-# LANGUAGE TemplateHaskell #-}
Then, after declaring the datatype (let's say Foo
), add makeLenses ''Foo
on a separate line (if you do it before the type is declared, you'll get a “not in scope” error – see the section at the top of this page):
data Foo = Foo {
_x :: Int,
_y :: Bool }
makeLenses
''Foo
This would generate the following lenses, which can be used to access the fields of Foo
:
x ::Lens'
Foo Int x f foo = (\x' -> foo {_x = x'})<$>
f (_x foo) y ::Lens'
Foo Bool y f foo = (\y' -> foo {_y = y'})<$>
f (_y foo)
(If you don't want a lens to be generated for some field, don't prefix it with “_”.)
If you want to create lenses for many types, you can do it all in one place like this (of course, instead you just can use makeLenses
several times if you feel it would be more readable):
data Foo = ... data Bar = ... data Quux = ...concat
<$>
mapM
makeLenses
[''Foo, ''Bar, ''Quux]
When the data type has type parameters, it's possible for a lens to do a polymorphic update – i.e. change the type of the thing along with changing the type of the field. For instance, with this type
data Foo a = Foo { _x :: a, _y :: Bool }
the following lenses would be generated:
x ::Lens
(Foo a) (Foo b) a b y ::Lens'
(Foo a) Bool
However, when there are several fields using the same type parameter, type-changing updates are no longer possible:
data Foo a = Foo { _x :: a, _y :: a }
generates
x ::Lens'
(Foo a) a y ::Lens'
(Foo a) a
Finally, when the type has several constructors, some of fields may not be always present – for those, a Traversal
is generated instead. For instance, in this example y
can be present or absent:
data FooBar = Foo { _x :: Int, _y :: Bool } | Bar { _x :: Int }
and the following accessors would be generated:
x ::Lens'
FooBar Int y ::Traversal'
FooBar Bool
So, to get _y
, you'd have to either use (^?
) if you're not sure it's there, or (^?!
) if you're absolutely sure (and if you're wrong, you'll get an exception). Setting and updating _y
can be done as usual.