Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C#
  4. Becoming functional: adding Option of T to List when IsSome only

Becoming functional: adding Option of T to List when IsSome only

Scheduled Pinned Locked Moved C#
csharpcomfunctionaltutorialquestion
3 Posts 2 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • B Offline
    B Offline
    Bernhard Hiller
    wrote on last edited by
    #1

    Eventually I decided to start with the functional concept and installed the LanguageExt library (see GitHub - louthy/language-ext: C# functional language extensions - a base class library for functional programming[^] ). In our code base, there is a class which is full of bool TryGet(some parameters, out T result) functions - I want to change them to Option TryGet(some parameters). But then, things start to look ugly at a different level. E.g.

    List result = new List();
    ...
    foreach (IIntersectionInfo intersection in intersections)
    {
    Option angle = m_Geometry.TryGetAnglesForPosition(intersectionPoint, _name);
    if (angle.IsNone)
    {
    Logger.LogWarning(Name, $"Cannot determine angle for position '{intersectionPoint}' corresponding to pixel '{pixel}'.");
    }
    else
    {
    result.Add(angle.IfNone(PointF.Empty));
    }
    }

    There are two kinds of ugliness: - I have to use the IfNone(PointF.Empty) clause even when angle is guaranteed to be Some there. - I do not know how to get rid of the foreach in this situation. How can the code become clean?

    Oh sanctissimi Wilhelmus, Theodorus, et Fredericus!

    Richard DeemingR 1 Reply Last reply
    0
    • B Bernhard Hiller

      Eventually I decided to start with the functional concept and installed the LanguageExt library (see GitHub - louthy/language-ext: C# functional language extensions - a base class library for functional programming[^] ). In our code base, there is a class which is full of bool TryGet(some parameters, out T result) functions - I want to change them to Option TryGet(some parameters). But then, things start to look ugly at a different level. E.g.

      List result = new List();
      ...
      foreach (IIntersectionInfo intersection in intersections)
      {
      Option angle = m_Geometry.TryGetAnglesForPosition(intersectionPoint, _name);
      if (angle.IsNone)
      {
      Logger.LogWarning(Name, $"Cannot determine angle for position '{intersectionPoint}' corresponding to pixel '{pixel}'.");
      }
      else
      {
      result.Add(angle.IfNone(PointF.Empty));
      }
      }

      There are two kinds of ugliness: - I have to use the IfNone(PointF.Empty) clause even when angle is guaranteed to be Some there. - I do not know how to get rid of the foreach in this situation. How can the code become clean?

      Oh sanctissimi Wilhelmus, Theodorus, et Fredericus!

      Richard DeemingR Offline
      Richard DeemingR Offline
      Richard Deeming
      wrote on last edited by
      #2

      If you didn't want to log the failures, it could be as simple as:

      m_Geometry.TryGetAnglesForPosition(intersectionPoint, _name).IfSome(result.Add);

      Otherwise, something like this should work:

      m_Geometry.TryGetAnglesForPosition(intersectionPoint, _name).Match(
      point => result.Add(point),
      () => Logger.LogWarning(Name, $"Cannot determine angle for position '{intersectionPoint}' corresponding to pixel '{pixel}'."));

      There's also the C# 8 property patterns:

      if (m_Geometry.TryGetAnglesForPosition(intersectionPoint, _name) is { IsSome: true } angle)
      {
      angle.IfSome(result.Add);
      }
      else
      {
      Logger.LogWarning(Name, $"Cannot determine angle for position '{intersectionPoint}' corresponding to pixel '{pixel}'.");
      }

      Or you could define a deconstructor as an extension method:

      public static class OptionTExtensions
      {
      public static void Deconstruct<T>(this Option<T> option, bool isSome, T value)
      {
      isSome = option.IsSome;
      value = isSome ? (T)option : default;
      }
      }
      ...
      var (isSome, point) = m_Geometry.TryGetAnglesForPosition(intersectionPoint, _name);
      if (isSome)
      {
      result.Add(point);
      }
      else
      {
      Logger.LogWarning(Name, $"Cannot determine angle for position '{intersectionPoint}' corresponding to pixel '{pixel}'.");
      }


      "These people looked deep within my soul and assigned me a number based on the order in which I joined." - Homer

      "These people looked deep within my soul and assigned me a number based on the order in which I joined" - Homer

      B 1 Reply Last reply
      0
      • Richard DeemingR Richard Deeming

        If you didn't want to log the failures, it could be as simple as:

        m_Geometry.TryGetAnglesForPosition(intersectionPoint, _name).IfSome(result.Add);

        Otherwise, something like this should work:

        m_Geometry.TryGetAnglesForPosition(intersectionPoint, _name).Match(
        point => result.Add(point),
        () => Logger.LogWarning(Name, $"Cannot determine angle for position '{intersectionPoint}' corresponding to pixel '{pixel}'."));

        There's also the C# 8 property patterns:

        if (m_Geometry.TryGetAnglesForPosition(intersectionPoint, _name) is { IsSome: true } angle)
        {
        angle.IfSome(result.Add);
        }
        else
        {
        Logger.LogWarning(Name, $"Cannot determine angle for position '{intersectionPoint}' corresponding to pixel '{pixel}'.");
        }

        Or you could define a deconstructor as an extension method:

        public static class OptionTExtensions
        {
        public static void Deconstruct<T>(this Option<T> option, bool isSome, T value)
        {
        isSome = option.IsSome;
        value = isSome ? (T)option : default;
        }
        }
        ...
        var (isSome, point) = m_Geometry.TryGetAnglesForPosition(intersectionPoint, _name);
        if (isSome)
        {
        result.Add(point);
        }
        else
        {
        Logger.LogWarning(Name, $"Cannot determine angle for position '{intersectionPoint}' corresponding to pixel '{pixel}'.");
        }


        "These people looked deep within my soul and assigned me a number based on the order in which I joined." - Homer

        B Offline
        B Offline
        Bernhard Hiller
        wrote on last edited by
        #3

        Thanks, that was the major step for this issue. Afterwards, I could figure out the var tmp = intersections.Map(_intersection => m_Geometry.TryGet...ToList() monstrosity abolishing the foreach(... intersections). Functional programming feels odd when trying it for the first time.

        Oh sanctissimi Wilhelmus, Theodorus, et Fredericus!

        1 Reply Last reply
        0
        Reply
        • Reply as topic
        Log in to reply
        • Oldest to Newest
        • Newest to Oldest
        • Most Votes


        • Login

        • Don't have an account? Register

        • Login or register to search.
        • First post
          Last post
        0
        • Categories
        • Recent
        • Tags
        • Popular
        • World
        • Users
        • Groups