Haskell template for OO abstract types

I come from OO languages ​​and am currently trying to develop an application in Haskell. I am trying to use what would be an abstract class in OO languages, but this does not seem to be suitable for the Haskell type system (and probably most functional languages).

In, say, Java, the minimal code of what I'm trying to express is likely to look something like this.

abstract class Transformation {
    public abstract void transform(Image image);
}

class ResizeTransformation extends Transformation {
    public void transform(Image image) {
        // resize the image
    }
}

// some other classes extending Transformation

class Worker {
    public void applyTransformations(Image image, Transformation[] trs) {
        for (Transformation t: trs) {
            t.transform(image);
        }
    }
}

class Parser {
    public Transformation parseTransformation(String rawTransformation) {
        // return ResizeTransformation or some other concrete transformation
    }
}

I tried to express this in Haskell with a class Transformationand create multiple instances for each transformation, but I was stuck in Parser, since it seems impossible to return an abstract type.

Here is more or less what my Haskell code looks like:

class Transformation a where
  transform :: Image -> a -> Image

data Resize = Resize
    { newHeight :: Int
    , newWidth  :: Int
    } deriving (Show)


instance Transformation Resize where
    transform image resize = -- resize the image

applyTransformations :: (Transformation a) => Image -> [a] -> Image
applyTransformations image transformations = foldl transform image transformations

And I would like to have a function with such a signature

parseTransformation :: (Transformation a) => String -> Maybe a

, , Maybe Resize could not deduce a ~ Resize, .

- , - Haskell. , , , Haskell.

+4
1

, , , .

: , Haskell, , .

/

, , Java.

abstract class Transformation {
    public abstract void transform(Image image);
}

, , , ,

class Transformation a where
  transform :: Image -> a -> Image

data Resize = Resize
    { newHeight :: Int
    , newWidth  :: Int
    } deriving (Show)

instance Transformation Resize where
    transform image resize = -- resize the image

-

type Processor = Image -> Image
data Transformation = Transformation
                      { name      :: String
                      , args      :: String
                      , processor :: Processor
                      }

parseTransformation :: String -> String -> Maybe Transformation
parseProcessor      :: String -> String -> Maybe Processor

resizeProcessor :: ResizeInfo -> Processor
cropProcessor   :: CropInfo -> Processor

ResizeInfo CropInfo parseProcessor . Transformation , .

, , - , DI Java. :

public interface Storage {
    public void load(StoredObject o);
    public void save(StoredObject o);
}

public class S3Storage implements Storage {
    // some implementation
}

public class LocalStorage implements Storage {
    // some implementation
}

.. .

, , Haskell, .

,

data StoredObject = StoredObject
                  { uniqueId      :: String
                  , content       :: Maybe ByteString
                  } deriving (Show)

class Storage a where
    load :: a -> StoredObject -> IO (Either StorageError StoredObject)
    save :: a -> StoredObject -> IO (Either StorageError ())

LocalStorage S3Storage Storage .

data LocalStorage = LocalStorage
                  { baseDir :: String
                  }
instance Storage LocalStorage where
    save = -- implementation
    load = -- implementation

, -

downloadHandler :: (Storage a) => a -> IO ()
downloadHandler storage = -- process download

, , , , . .

runApp :: String -> IO ()
runApp "local" = run makeLocalStorage
runApp "s3"    = run makeS3Storage
runApp storage = putStrLn ("no storage named " ++ storage) >> exitFailure

run :: (Storage a) => a -> IO ()
run storage = -- run with my storage

.

0

All Articles