I have the following issue:
I have 2 types that are paremterized and that should work with a generic function if both types have the same type parameters
type A<'a> = A of 'a
type C<'a> = C of 'a
let inline save ((A a) :A<'a>) ((C c):C<'a>) = saveToDB (a :: c :: []) |> ignore
save (A 1) (C 2)
save (A "1") (C "2")
Now imagine a function that should execute the save
but with different types which will be instantiated via some indicator
let inline save indicator (otherval:C<'a>) =
match indicator with
| "i" -> save (A 1) otherval
| "s" -> save (A "s") otherval
In this case I get an error on | "s" -> adder (A "s") otherval
saying that otherval
should be of type C<int>
Any idea on how to approach this?
答案 0 :(得分:3)
基于Julien Roncaglia的回答,这种方法至少应该是类型安全的,因为我们在守卫时使用:
let inline save ((A a) :A<'a>) ((C c):C<'a>) = saveToDB (a :: c :: []) |> ignore
let boxToGenericC<'a, 'b> (c: C<'a>) =
unbox<C<'b>>(box(c))
let save1 indicator (otherval:C<'a>) =
match indicator with
| "i" when typeof<'a> = typeof<System.Int32> -> save (A 1) (boxToGenericC<'a, int> otherval)
| "s" when typeof<'a> = typeof<string>-> save (A "s") (boxToGenericC<'a, string> otherval)
并尝试执行save1 "s" (C 1)
会导致模式匹配失败。
答案 1 :(得分:2)
虽然它可能不是一个“干净”的设计(我没有看到一个没有改变你的规格),你可以告诉类型系统停止关怀:
.hovereffect img{
display: block;
position: relative;
max-width: none;
width: calc(100% + 20px);
-webkit-transition: opacity 0.35s, -webkit-transform 0.35s;
transition: opacity 0.35s, transform 0.35s;
-webkit-transform: translate3d(-10px,0,0);
transform: translate3d(-10px,0,0);
-webkit-backface-visibility: hidden;
backface-visibility: hidden;
}
.hovereffect:hover img{
opacity: 0;
filter: alpha(opacity=40);
-webkit-transform: translate3d(0,0,0);
transform: translate3d(0,0,0);
}
.hovereffect a, .hovereffect p{
color: #FFF;
opacity: 0;
filter: alpha(opacity=0);
-webkit-transition: opacity 0.35s, -webkit-transform 0.35s;
transition: opacity 0.35s, transform 0.35s;
-webkit-transform: translate3d(100%,0,0);
transform: translate3d(100%,0,0);
}
.hovereffect:hover a, .hovereffect:hover p{
opacity: 1;
filter: alpha(opacity=100);
-webkit-transform: translate3d(0,0,5);
transform: translate3d(0,0,0);
text-decoration: none;
color: #fff;
}
它有效,但你失去了一些检查:
let inline firstval indicator:A<'a> =
let boxed =
match indicator with
| "i" -> box (A 1)
| "s" -> box (A "s")
unbox<A<'a>> boxed
let inline save2 indicator (otherval:C<'a>) =
save (firstval indicator) otherval
save2 "i" (C 2)
save2 "s" (C "2")
无法将类型为'A`1 [System.String]'的对象转换为'A`1 [System.Int32]'。