Skip to content

Instantly share code, notes, and snippets.

@maxim-saplin
Last active October 29, 2023 13:07
Show Gist options
  • Save maxim-saplin/b14818de07e8094b6e8a230c75fae103 to your computer and use it in GitHub Desktop.
Save maxim-saplin/b14818de07e8094b6e8a230c75fae103 to your computer and use it in GitHub Desktop.
Example of functional style in Dart using features from version 3.1
// sealed classes are abstract (can't be instatiated) and can only be
// implemented in the same library (library in Dart is one file be default)
sealed class Message {
}
class TextMessage implements Message {
final String content;
TextMessage(this.content);
}
class ImageMessage implements Message {
final String content;
final String imageUrl;
ImageMessage(this.content, this.imageUrl);
}
class FileMessage implements Message {
final String content;
final String fileUrl;
FileMessage(this.content, this.fileUrl);
}
// Extract fields from a message and return as Record
(String type, String content, String url) getMessage(Message message) {
// using switch expression, https://dart.dev/language/branches#switch-expressions
return switch (message) {
TextMessage(:var content) => ('Text', content, ''),
ImageMessage(:var content, :var imageUrl) => ('Image', content, imageUrl),
FileMessage(:var content, :var fileUrl) => ('File', content, fileUrl)
};
}
void printTexts(List<Message> messages) {
// using normal switch statement
for (var m in messages) {
switch (m) {
case TextMessage(content: final text): print(text);
case ImageMessage(): print('<img>');
default: print('<smth-else>');
}
}
}
void main() {
var m0 = TextMessage('Hello, John!'), m1 = TextMessage('Hi, Jack!');
var m2 = ImageMessage('Check this out', 'https://example.com/image1.jpg');
var m3 = FileMessage('Important document', 'https://example.com/document1.pdf');
var messages = [m0, m1, m2, m3];
for (var m in messages){
print(getMessage(m));
}
printTexts(messages);
}
// Output
//
// (Text, Hello, John!, )
// (Text, Hi, Jack!, )
// (Image, Check this out, https://example.com/image1.jpg)
// (File, Important document, https://example.com/document1.pdf)
// Hello, John!
// Hi, Jack!
// <img>
// <smth-else>
-- Define message types
data Message = TextMessage String
| ImageMessage String String
| FileMessage String String
deriving (Show)
-- Extract fields from a message and return as a tuple
getMessage :: Message -> (String, String, String)
getMessage (TextMessage content) = ("Text", content, "")
getMessage (ImageMessage content imageUrl) = ("Image", content, imageUrl)
getMessage (FileMessage content fileUrl) = ("File", content, fileUrl)
-- Print text of messages
printTexts :: [Message] -> IO ()
printTexts [] = return ()
printTexts (TextMessage content : messages) = do
putStrLn content
printTexts messages
printTexts (ImageMessage _ _ : messages) = do
putStrLn "<img>"
printTexts messages
printTexts (_ : messages) = do
putStrLn "<smth-else>"
printTexts messages
main :: IO ()
main = do
-- Create sample messages
let m0 = TextMessage "Hello, John!"
m1 = TextMessage "Hi, Jack!"
m2 = ImageMessage "Check this out" "https://example.com/image1.jpg"
m3 = FileMessage "Important document" "https://example.com/document1.pdf"
messages = [m0, m1, m2, m3]
-- Print messages using getMessage
mapM_ (print . getMessage) messages
-- Print texts of messages using printTexts
printTexts messages
-- Output
--
-- ("Text","Hello, John!","")
-- ("Text","Hi, Jack!","")
-- ("Image","Check this out","https://example.com/image1.jpg")
-- ("File","Important document","https://example.com/document1.pdf")
-- Hello, John!
-- Hi, Jack!
-- <img>
-- <smth-else>
abstract class Message {
String get content;
String getMessage();
}
class TextMessage implements Message {
@override
final String content;
TextMessage(this.content);
String get url => '';
String get type => 'Text';
@override
String getMessage() {
return '($type, $content, $url)';
}
}
class ImageMessage implements Message {
@override
final String content;
final String imageUrl;
ImageMessage(this.content, this.imageUrl);
String get url => imageUrl;
String get type => 'Image';
@override
String getMessage() {
return '($type, $content, $url)';
}
}
class FileMessage implements Message {
@override
final String content;
final String fileUrl;
FileMessage(this.content, this.fileUrl);
String get url => fileUrl;
String get type => 'File';
@override
String getMessage() {
return '($type, $content, $url)';
}
}
void printTexts(List<Message> messages) {
for (var m in messages) {
if (m is TextMessage) {
print(m.content);
} else if (m is ImageMessage) {
print('<img>');
} else {
print('<smth-else>');
}
}
}
void main() {
var m0 = TextMessage('Hello, John!'), m1 = TextMessage('Hi, Jack!');
var m2 = ImageMessage('Check this out', 'https://example.com/image1.jpg');
var m3 = FileMessage('Important document', 'https://example.com/document1.pdf');
var messages = [m0, m1, m2, m3];
for (var m in messages) {
print(m.getMessage());
}
printTexts(messages);
}
// Output
//
// (Text, Hello, John!, )
// (Text, Hi, Jack!, )
// (Image, Check this out, https://example.com/image1.jpg)
// (File, Important document, https://example.com/document1.pdf)
// Hello, John!
// Hi, Jack!
// <img>
// <smth-else>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment