# Practical Functional Programming - Find repeated characters | Part 1self.__wrap_b=(t,n,e)=>{e=e||document.querySelector(`[data-br="\${t}"]`);let s=e.parentElement,r=B=>e.style.maxWidth=B+"px";e.style.maxWidth="";let o=s.clientWidth,u=s.clientHeight,a=o/2-.25,c=o+.5,p;if(o){for(r(a),a=Math.max(e.scrollWidth,a);a+1<c;)p=Math.round((a+c)/2),r(p),s.clientHeight===u?c=p:a=p;r(c*n+o*(1-n))}e.__wrap_o||(typeof ResizeObserver!="undefined"?(e.__wrap_o=new ResizeObserver(()=>{self.__wrap_b(0,+e.dataset.brr,e)})).observe(s): false&&0)};self.__wrap_b(":R5crbbbja:",1)

Sandro Maglione

Functional programming

Practical Functional Programming step by step is a series in which we are going to uncover the principles of functional programming and effective coding one small piece at the time.

Starting from a complete code example, we are going to learn step by step what makes a good functional code and what are the benefits of applying a functional programming paradigm to your codebase.

## Find repeated characters

The function we are going to uncover in this first part of the series is based on the following instructions:

Given a `String`, find all the characters that are repeated 2 or more times and return a new `String` containing only these characters.

I am going to show you the solution to this assignment in three different languages: Haskell, Typescript, and Dart. We are going to learn how functional programming is used to solve the same problem in different languages.

This practical functional programming series aims to make you understand a complete functional programming function by explaining how each method works.

Haskell is a pure functional programming language. It means that you are strictly required to write functional code. The solution is the following:

``````import Data.Map
( Map,
empty,
filter,
insert,
keys,
member,
)
import Prelude hiding (filter)

twotimes :: String -> String
twotimes str = keys \$ filter (> 1) (buildmap str)
where
buildmap :: String -> Map Char Int
buildmap =
foldl
( \acc x ->
if member x acc
then adjust (+ 1) x acc
else insert x 1 acc
)
empty``````

### Typescript solution

In order to use functional programming in typescript, we are going to use the amazing fp-ts library. The solution is the following:

``````import * as O from 'fp-ts/Option';
import { trivial } from 'fp-ts/Ord';
import { reduce } from 'fp-ts/lib/Array';
import { pipe } from 'fp-ts/lib/function';
import { Eq as eqString } from 'fp-ts/string';
import { filter, keys, modifyAt, upsertAt } from 'fp-ts/lib/Map';

const buildmap = (str: string): Map<string, number> =>
pipe(
str.split(''),
reduce(new Map<string, number>(), (acc, x) =>
pipe(
acc,
modifyAt(eqString)(x, (n) => n + 1),
O.getOrElse(() => pipe(acc, upsertAt(eqString)(x, 1)))
)
)
);

const twotimes = (str: string): string =>
pipe(
str,
buildmap,
filter((n) => n > 1),
keys(trivial),
(strList) => strList.join('')
);``````

### Dart solution

Dart is not a functional language. We are going to use the fpdart library to code in dart using functional programming. The solution is the following:

``````import 'package:fpdart/fpdart.dart';

Map<String, int> buildmap(String str) => str.split('').foldLeft(
<String, int>{},
(acc, x) => {
...acc,
x: (acc[x] ?? 0) + 1,
},
);

String twotimes(String str) => buildmap(str)
.entries
.where((map) => map.value > 1)
.map((map) => map.key)
.join('');``````

Take a look at the three solutions above. They may look different, but they are using the same logic to solve the same problem.

For this Part 1 of the series I am going to leave you thinking about the solutions above. Try to reason about what they are doing and see if you can recognise a pattern and understand how they work.

See you soon for Part 2!

### đŸ‘‹ăƒ»Interested in learning more, every week?

Every week I build a new open source project, with a new language or library, and teach you how I did it, what I learned, and how you can do the same. Join me and other 400+ readers.