-
I wanted to use public static ConsoleKeyInfo ReadKey(bool intercept)
{
return ConsolePal.ReadKey(intercept);
} However, the built-in trait namespace LanguageExt.Sys
{
public static class Console<RT> where RT : struct, HasConsole<RT>
{
public static Eff<RT, ConsoleKeyInfo> readKey
{
get
{
... So I thought I need to create all the setup of my new trait, its implementation, static class with functions to work with console, runtime and e.t.c. (by following this wiki page example). I've created all of these, but unforunately I can't use static class MyConsole<RT>
where RT : struct, HasMyConsole<RT>, HasMyCancel<RT>
{
public static Eff<RT, ConsoleKeyInfo> readKey(bool hideKeys)
=> default(RT)
.ConsoleEff.Bind(
(MyConsoleIO e) =>
e.ReadKey(hideKeys)
.Match(
new Func<ConsoleKeyInfo, Eff<ConsoleKeyInfo>>(SuccessEff),
() => FailEff<ConsoleKeyInfo>(Error.New("end of stream"))));
public static Producer<RT, ConsoleKeyInfo, Unit> readKeys(bool hideKeys) => // Error: no conversion from RT to HasCancel<RT>
from ln in readKey(hideKeys)
from __ in yield(ln)
select unit;
} So, if I need to use a Producer class with my own runtime and traits implementations, do I need to use only built-in one like |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment
-
First thing is that you can't have your own The key thing to note is that because the 'traits' are just interfaces, they can be extended through inheritance. I would 'extend' the current console trait and interface: public interface ConsoleExtendedIO : ConsoleIO
{
public Option<ConsoleKeyInfo> ReadKey(bool hideKeys);
}
public interface HasConsoleExtended<RT> : HasConsole<RT>
where RT : struct, HasCancel<RT>
{
Eff<RT, ConsoleExtendedIO> ConsoleExtendedEff { get; }
} Then implement your extended console: public readonly struct YourExtendedConsoleImplementation : ConsoleExtendedIO
{
public readonly static ConsoleExtendedIO Default =
new YourExtendedConsoleImplementation();
public Option<ConsoleKeyInfo> ReadKey(bool hideKeys) =>
System.Console.ReadKey(hideKeys);
// ... all the inehrited methods can just call LanguageExt.Sys.Live.ConsoleIO.*
} And create an extended console static class: public static class ConsoleExtended<RT>
where RT : struct, HasConsoleExtended<RT>
{
public static Eff<RT, ConsoleKeyInfo> readKey(bool hideKeys) =>
default(RT).ConsoleExtendedEff
.Bind(static e =>
e.ReadKey(hideKeys)
.Match(Some: SuccessEff<ConsoleKeyInfo>,
None: () => FailEff<ConsoleKeyInfo>(Error.New("end of stream"))));
} Then in your runtime, you can implement public readonly struct Runtime :
HasCancel<Runtime>,
HasConsoleExtended<Runtime>,
Has...
{
public Eff<Runtime, Traits.ConsoleIO> ConsoleEff =>
SuccessEff(YourExtendedConsoleImplementation.Default);
public Eff<Runtime, Traits.ConsoleExtendedIO> ConsoleExtendedEff =>
SuccessEff(YourExtendedConsoleImplementation.Default);
}
Then you can use the trait ConsoleExtended<RT>.readKey(true) You don't have to extend You will however have to use the built-in |
Beta Was this translation helpful? Give feedback.
First thing is that you can't have your own
HasCancel<RT>
unless you extend the original trait/interface. It is the only thing that's built-in to the asynchronous effects (Aff
) system, because it's the trait that allows you to cancel an asynchronous process.The key thing to note is that because the 'traits' are just interfaces, they can be extended through inheritance. I would 'extend' the current console trait and interface: