The user interface of the core language
- data Ord a => Range a = Range {
- lowerBound :: Maybe a
- upperBound :: Maybe a
- data a :> b = a :> b
- class Set a where
- universal :: a
- type Length = Int
- class Typeable a => Storable a
- data Data a
- dataSize :: Data a -> Size a
- class Typeable (Internal a) => Computable a where
- type Internal a
- eval :: Computable a => a -> Internal a
- value :: Storable a => a -> Data a
- array :: Storable a => Size a -> a -> Data a
- arrayLen :: Storable a => Data Length -> [a] -> Data [a]
- unit :: Data ()
- true :: Data Bool
- false :: Data Bool
- size :: forall a. Storable a => Data [a] -> [Range Length]
- cap :: (Storable a, Size a ~ Range b, Ord b) => Range b -> Data a -> Data a
- getIx :: Storable a => Data [a] -> Data Int -> Data a
- setIx :: Storable a => Data [a] -> Data Int -> Data a -> Data [a]
- class RandomAccess a where
- class (Num a, Primitive a, Num (Size a)) => Numeric a
- noInline :: (Computable a, Computable b) => String -> (a -> b) -> a -> b
- ifThenElse :: (Computable a, Computable b) => Data Bool -> (a -> b) -> (a -> b) -> a -> b
- while :: Computable state => (state -> Data Bool) -> (state -> state) -> state -> state
- parallel :: Storable a => Data Length -> (Data Int -> Data a) -> Data [a]
- class Program a
- showCore :: forall a. Program a => a -> String
- showCoreWithSize :: forall a. Program a => a -> String
- printCore :: Program a => a -> IO ()
- printCoreWithSize :: Program a => a -> IO ()
- module Feldspar.Core.Functions
Documentation
Range | |
|
Heterogeneous list
a :> b |
class Typeable a => Storable a Source
Storable types (zero- or higher-level arrays of primitive data).
A wrapper around Expr
to allow observable sharing (see
Feldspar.Core.Ref) and for memoizing size information.
class Typeable (Internal a) => Computable a Source
Computable types. A computable value completely represents a core program,
in such a way that
preserves semantics, but
not necessarily syntax.
internalize
.
externalize
The terminology used in this class comes from thinking of the Data
type as
the "internal" core language and the Feldspar.Core API as the
"external" core language.
Storable a => Computable (Data a) | |
Storable a => Computable (Vector (Data a)) | |
Storable a => Computable (Vector (Vector (Data a))) | |
(Computable a, Computable b) => Computable (a, b) | |
(Computable a, Computable b, Computable c) => Computable (a, b, c) | |
(Computable a, Computable b, Computable c, Computable d) => Computable (a, b, c, d) |
eval :: Computable a => a -> Internal aSource
The semantics of any Computable
type
array :: Storable a => Size a -> a -> Data aSource
Like value
but with an extra Size
argument that can be used to increase
the size beyond the given data.
Example 1:
array (10 :> 20 :> universal) [] :: Data [[Int]]
gives an uninitialized 10x20 array of Int
elements.
Example 2:
array (10 :> 20 :> universal) [[1,2,3]] :: Data [[Int]]
gives a 10x20 array whose first row is initialized to [1,2,3]
.
size :: forall a. Storable a => Data [a] -> [Range Length]Source
Returns the size of each level of a multi-dimensional array, starting with the outermost level.
getIx :: Storable a => Data [a] -> Data Int -> Data aSource
Look up an index in an array (see also !
)
setIx :: Storable a => Data [a] -> Data Int -> Data a -> Data [a]Source
:
setIx
arr i a
Replaces the value at index i
in the array arr
with the value a
.
class RandomAccess a whereSource
Storable a => RandomAccess (Data [a]) | |
RandomAccess (Vector a) |
noInline :: (Computable a, Computable b) => String -> (a -> b) -> a -> bSource
Constructs a non-primitive, non-inlined function.
The normal way to make a non-primitive function is to use an ordinary Haskell function, for example:
myFunc x = x * 4 + 5
However, such functions are inevitably inlined into the program expression
when applied. noInline
can be thought of as a way to protect a function
against inlining (but later transformations may choose to inline anyway).
Ideally, it should be posssible to reuse such a function several times, but
at the moment this does not work. Every application of a noInline
function
results in a new copy of the function in the core program.
ifThenElse :: (Computable a, Computable b) => Data Bool -> (a -> b) -> (a -> b) -> a -> bSource
:
ifThenElse
cond thenFunc elseFunc
Selects between the two functions thenFunc
and elseFunc
depending on
whether the condition cond
is true or false.
while :: Computable state => (state -> Data Bool) -> (state -> state) -> state -> stateSource
While-loop
while cont body :: state -> state
:
-
state
is the type of the state. -
cont
determines whether or not to continue based on the current state. -
body
computes the next state from the current state. - The result is a function from initial state to final state.
parallel :: Storable a => Data Length -> (Data Int -> Data a) -> Data [a]Source
Parallel array
parallel l ixf
:
-
l
is the length of the resulting array (outermost level). -
ifx
is a function that maps each index in the range[0 .. l-1]
to its element.
Since there are no dependencies between the elements, the compiler is free to compute the elements in any order, or even in parallel.
Types that represent core language programs
Computable a => Program a | |
(Computable a, Computable b, Computable c, Computable d, Computable e) => Program (a -> b -> c -> d -> e) | |
(Computable a, Computable b, Computable c, Computable d) => Program (a -> b -> c -> d) | |
(Computable a, Computable b, Computable c) => Program (a -> b -> c) | |
(Computable a, Computable b) => Program (a -> b) | |
(Computable a, Computable b) => Program (a, b) | |
(Computable a, Computable b, Computable c) => Program (a, b, c) | |
(Computable a, Computable b, Computable c, Computable d) => Program (a, b, c, d) |
showCoreWithSize :: forall a. Program a => a -> StringSource
Shows the core code with size information as comments.
printCoreWithSize :: Program a => a -> IO ()Source
printCoreWithSize = putStrLn . showCoreWithSize
module Feldspar.Core.Functions