diff --git a/CHANGELOG.md b/CHANGELOG.md
index 57a6d7c..b225db5 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -9,6 +9,9 @@ The `Unreleased` section name is replaced by the expected version of next releas
## [Unreleased]
### Added
+
+- `StreamName.Category` + `category`: Extracts the category portion of a streamName [#84](https://github.com/jet/FsCodec/pull/84)
+
### Changed
### Removed
### Fixed
diff --git a/README.md b/README.md
index ade1359..9cdd5b4 100644
--- a/README.md
+++ b/README.md
@@ -494,6 +494,10 @@ module StreamName =
(* Splitting: functions/Active patterns for (i.e. generated via `parse`, `create` or `compose`) well-formed Stream Names
Will throw if presented with malformed strings [generated via alternate means] *)
+ /// Extracts the category portion of the StreamName
+ let category (x : StreamName) : string = ...
+ let (|Category|) = category~~~~
+
// Splits a well-formed Stream Name of the form {category}-{streamId} into its two elements.
// Throws InvalidArgumentException
if it does not adhere to the well known format (i.e. if it was not produced by `parse`).
// Inverse of create
diff --git a/src/FsCodec/StreamName.fs b/src/FsCodec/StreamName.fs
index bf322b9..e35fe31 100755
--- a/src/FsCodec/StreamName.fs
+++ b/src/FsCodec/StreamName.fs
@@ -87,6 +87,13 @@ module StreamName =
(* Splitting: functions/Active patterns for (i.e. generated via `parse`, `create` or `compose`) well-formed Stream Names
Will throw if presented with malformed strings [generated via alternate means] *)
+ /// Extracts the category portion of the StreamName
+ let category (x : StreamName) =
+ let raw = toString x
+ raw.Substring(0, raw.IndexOf '-')
+ /// Extracts the category portion of a StreamName
+ let (|Category|) = category
+
/// Splits a well-formed Stream Name of the form {category}-{streamId} into its two elements.
/// Throws InvalidArgumentException if it does not adhere to the well known format (i.e. if it was not produced by `parse`).
/// Inverse of create
diff --git a/tests/FsCodec.NewtonsoftJson.Tests/Examples.fsx b/tests/FsCodec.NewtonsoftJson.Tests/Examples.fsx
index 00d5faa..855af13 100755
--- a/tests/FsCodec.NewtonsoftJson.Tests/Examples.fsx
+++ b/tests/FsCodec.NewtonsoftJson.Tests/Examples.fsx
@@ -145,9 +145,9 @@ module Events =
/// Pattern to determine whether a given {category}-{streamId} StreamName represents the stream associated with this Aggregate
/// Yields a strongly typed id from the streamId if the Category does match
- let (|StreamName|_|) = function
- | FsCodec.StreamName.CategoryAndId (Category, ClientId.Parse clientId) -> Some clientId
- | _ -> None
+ let [] (|StreamName|_|) = function
+ | FsCodec.StreamName.CategoryAndId (Category, ClientId.Parse clientId) -> ValueSome clientId
+ | _ -> ValueNone
type Added = { item : string }
type Removed = { name : string }
diff --git a/tests/FsCodec.SystemTextJson.Tests/Examples.fsx b/tests/FsCodec.SystemTextJson.Tests/Examples.fsx
index 41dc4e8..81a69f3 100755
--- a/tests/FsCodec.SystemTextJson.Tests/Examples.fsx
+++ b/tests/FsCodec.SystemTextJson.Tests/Examples.fsx
@@ -147,9 +147,9 @@ module Events =
/// Pattern to determine whether a given {category}-{streamId} StreamName represents the stream associated with this Aggregate
/// Yields a strongly typed id from the streamId if the Category does match
- let (|StreamName|_|) = function
- | FsCodec.StreamName.CategoryAndId (Category, ClientId.Parse clientId) -> Some clientId
- | _ -> None
+ let [] (|StreamName|_|) = function
+ | FsCodec.StreamName.CategoryAndId (Category, ClientId.Parse clientId) -> ValueSome clientId
+ | _ -> ValueNone
type Added = { item : string }
type Removed = { name : string }