LINQ相当于f#的builder.Zero()?

时间:2016-12-16 23:29:37

标签: c# f# monoids

所以,我已经沉迷于f#的计算表达式和自定义构建器。我必须在日常工作的大部分时间里使用c#,但仍然希望将LINQ表达式与我自己的monads / monoids一起使用。有人知道f#的panorama = map.getStreetView(); 方法是否类似?

Relevant f# docs

这是我在f#中做的事情:

Zero

2 个答案:

答案 0 :(得分:10)

我不确定你在这里问的是什么,但我会试一试。考虑澄清问题。

在monadic工作流程中,C#中的等效词if没有else

from a in b
where c(a)
select a

逻辑上这相当于(使用你的Bind,Return和Zero)

Bind(b, a => c(a) ? Return(a) : Zero)

但是C#不会将where子句降低为SelectMany(这就是C#所谓的Bind)。 C#将查询理解中的Where子句降低为对

的调用
Where(M<T>, Func<T, bool>)

简而言之:C#以查询理解的形式具有任意的monadic工作流程;具有Select,SelectMany,Where等的任何monadic类型都可以用于理解。但它并没有真正推广到具有明确零的加性monad。相反,“Where”应该具有我在上面提到的绑定操作的语义:如果项与谓词匹配,它应该具有与将单个值绑定到末尾相同的效果,如果不匹配则应该具有零值。

明显地“序列”在哪里做到了。如果你有[a,b,c]并希望过滤掉b,那就像连在一起[[a],[],[c]]一样。但是当然,实际构建和连接所有这些小序列会非常低效。 效果必须相同,但实际操作可以更有效。

C#的设计目的是支持非常具体的monad:序列monad通过yield和查询理解,继续comonad通过await,依此类推。我们没有将其设计为启用任意monadic工作流,如您在Haskell中所见。

这会回答你的问题吗?

答案 1 :(得分:2)

除了Eric的优秀答案外,还有一些代码:

require_once ("vendor/autoload.php");

if ($_POST) {
 echo "catch if";

 // Set your secret key: remember to change this to your live secret key in production
 // See your keys here: https://dashboard.stripe.com/account/apikeys

 StripeStripe::setApiKey("myApyKey");

 // Get the credit card details submitted by the form

 $token = $_POST['stripeToken'];

 // Create a charge: this will charge the user's card

 try {
  echo "charging";
  $charge = StripeCharge::create(array(
   "amount" => 1000, // Amount in cents
   "currency" => "eur",
   "source" => $token,
   "description" => "Example charge"
  ));
 }

 catch(StripeErrorCard $e) {

  // Since it's a decline, \Stripe\Error\Card will be caught

  $body = $e->getJsonBody();
  $err = $body['error'];
  print ('Status is:' . $e->getHttpStatus() . "\n");
  print ('Type is:' . $err['type'] . "\n");
  print ('Code is:' . $err['code'] . "\n");

  // param is '' in this case

  print ('Param is:' . $err['param'] . "\n");
  print ('Message is:' . $err['message'] . "\n");
 }

 catch(StripeErrorRateLimit $e) {

  // Too many requests made to the API too quickly

 }

 catch(StripeErrorInvalidRequest $e) {

  // Invalid parameters were supplied to Stripe's API

 }

 catch(StripeErrorAuthentication $e) {

  // Authentication with Stripe's API failed
  // (maybe you changed API keys recently)

 }

 catch(StripeErrorApiConnection $e) {

  // Network communication with Stripe failed

 }

 catch(StripeErrorBase $e) {

  // Display a very generic error to the user, and maybe send
  // yourself an email

 }

 catch(Exception $e) {

  // Something else happened, completely unrelated to Stripe

 }

C#的LINQ理解查找相应的扩展方法 var result = from value in Option.Some(5) where false select value; 。这是一个示例实现:

Where

public static Option<T> Where<T>(this Option<T> option, Func<T, bool> condition) { if(option is None || !condition(option.Value)) return None; return option; } 本身必须定义案例。